I'm trying to get the base address of a module from a process to which I have a handle to. I've tried this using the CreateToolhelp32Snapshot and EnumProcessModules methods.
The problem is it both methods return only these 5 DLLs:
underrail.exe
ndll.dll
wow64.dll
wow64win.dll
wow64cpu.dll
I know there should be more modules and trying to use this in other games returns the same 5 modules.
I have found some answers to the same question but both of them don't work out for me:
https://www.unknowncheats.me/forum/counterstrike-global-offensive/169030-modules.html
JNA - EnumProcessModules() not returning all DLLs?
The first one doesn't work since I can't use TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 as the flags in the method.
The second one doesn't work because I can't call the method EnumProcessModulesEx()
when I try to call Psapi.INSTANCE.EnumProcessModulesEx(...)
Here is a snippet of my code:
public static int getModuleBaseAddress(int process_id) {
DWORD pid = new DWORD(process_id);
HANDLE snapshot = null;
snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, pid);
MODULEENTRY32W module = new MODULEENTRY32W();
while(Kernel32.INSTANCE.Module32NextW(snapshot, module)) {
String s = Native.toString(module.szModule);
Pointer x = module.modBaseAddr;
System.out.println(s);
System.out.println(x);
System.out.println("---");
}
return 0;
}
Note that using Tlhelp32.TH32CS_SNAPMODULE32 doesn't return anything and Tlhelp32.TH32CS_SNAPALL returns the same as lhelp32.TH32CS_SNAPMODULE
Thanks to Daniel Widdis I have the answer.
Currently, the method EnumProcessModulesEx is not mapped into JNA so you have to make your own custom version of Psapi, which in my case looks something like this:
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Psapi;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;
public interface CustomPsapi extends Psapi{
Psapi INSTANCE = Native.load("psapi", Psapi.class,
W32APIOptions.DEFAULT_OPTIONS);
public void EnumProcessModulesEx(HANDLE hProcess, HMODULE[] lphModule, int cb,
IntByReference lpcbNeeded, int dwFilterFlag);
}
Then you can load your custom class and use the methods that you mapped.
public static CustomPsapi c_psapi = Native.load("psapi", CustomPsapi.class);
As for getting all the DLLs showing up correctly, you need to use the now mapped EnumProcessModulesEx method with the flag for all modules as the last argument (0x03)
so the method should look something like this:
c_psapi.EnumProcessModulesEx(process, modules, 1024, new IntByReference(1024), 0x03);
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 months ago.
Improve this question
I’m mid-way though writing a Minecraft 1.18.2 mod (Forge 40.1.80).
As this is the first Minecraft mod I am writing, I’m not too experienced in the field and have no idea what is causing this issue. When I try running the code I get this error (4 times): java: no suitable constructor found for Block(net.minecraft.world.level.block.state.BlockBehaviour.Properties). Any help would be greatly appreciated. The error appears here: "() -> new Block(ORE_PROPERTIES <-Here"
package com.example.factorytechv0_1.startup;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.Material;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.openjdk.nashorn.internal.ir.Block;
public class Registration {
private static final DeferredRegister<Block> BLOCKS = DeferredRegister.create((ResourceLocation) ForgeRegistries.BLOCKS, "factorytechv0_1");
private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, "factorytechv0_1");
public static void init() {
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());
ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
}
public static final BlockBehaviour.Properties ORE_PROPERTIES = BlockBehaviour.Properties.of(Material.STONE).strength(2f);
public static final Item.Properties ITEM_PROPERTIES = new Item.Properties().tab(ModSetup.ITEM_GROUP);
public static final RegistryObject<Block> CHROME_ORE_OVERWORLD = BLOCKS.register("chrome_ore_overworld", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> CHROME_ORE_OVERWORLD_ITEM = fromBlock(CHROME_ORE_OVERWORLD);
public static final RegistryObject<Block> CHROME_ORE_DEEPSLATE = BLOCKS.register("chrome_ore_deepslate", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> CHROME_ORE_DEEPSLATE_ITEM = fromBlock(CHROME_ORE_DEEPSLATE);
public static final RegistryObject<Block> HAFNIUM_ORE_NETHER = BLOCKS.register("hafnium_ore_nether", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> HAFNIUM_ORE_NETHER_ITEM = fromBlock(HAFNIUM_ORE_NETHER);
public static final RegistryObject<Block> TECHNETIUM_ORE_END = BLOCKS.register("technetium_ore_end", () -> new Block(ORE_PROPERTIES));
public static final RegistryObject<Item> TECHNETIUM_ORE_END_ITEM = fromBlock(TECHNETIUM_ORE_END);
public static <B extends Block> RegistryObject<Item> fromBlock(RegistryObject<B> block)
{
return ITEMS.register(block.getId().getPath(), () -> new BlockItem(block.get(), ITEM_PROPERTIES));
}
}
Here is the main initialisation file for the mod (if needed)
package com.example.factorytechv0_1;
import com.example.factorytechv0_1.startup.ClientSetup;
import com.example.factorytechv0_1.startup.ModSetup;
import com.example.factorytechv0_1.startup.Registration;
import com.mojang.logging.LogUtils;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.slf4j.Logger;
// The value here should match an entry in the META-INF/mods.toml file
#Mod("factorytechv0_1")
public class factorytechv0_1 {
// Directly reference a slf4j logger
private static final Logger LOGGER = LogUtils.getLogger();
public factorytechv0_1() {
// Register the deferred reg
Registration.init();
// Register the setup method for Modloading
IEventBus modbus = FMLJavaModLoadingContext.get().getModEventBus();
modbus.addListener(ModSetup::init);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> modbus.addListener(ClientSetup::init));
}
}
I think you might have the wrong import, perhaps intellij/eclipse suggested the wrong one for you.
import org.openjdk.nashorn.internal.ir.Block
This import looks weird, please remove it and replace it with something starting with net.minecraft.world.item.
Had a fast look at the API 1.18.2 , the class is abstract.
Here there is a little bit more to it, this shows how
https://moddingtutorials.org/o19/basic-blocks
What it is occurs when calling a new instance is BlockBehaviour.Properties is static but assigning it to the constructor argument instantly makes it an instance reference "no longer static" but it's methods are static, to overcome that, during construction the .of() method is called by that syntax notation and the properties are set "of the class" while the static state is being assigned to the constructor argument, in the hierarchy is a BlockBehaviour.Properties and is the copy of that instance available(for lack of better expression because it's static and only one copy).
After it is passed into the constructor, all the higher classes it extends have a constructor argument must be passed into as BlockBehaviour.Properties type so the first line in your customised class will have super(theblockpropargref); the theblockpropargref variable is now an instance and not static.
The looney point is the .of() method is called attached to the new instance customised class call but the BlockBehaviour.Properties is a class in the hierarchy of the new customised class so it searches it's own hierarchy for the .of() method signature and argument loading and finds it in it's own "static class" BlockBehaviour.Properties , the actual mad point is it must become an instance but must be called with a method to exist , but to not return a value from a method it must use a "void" method or be returning the type the instance variable is so it can only be assigned and exist during calling it before being made an instance of its type to be put on an instance variable teference
If you look at class Block it's used to "extend from" as normally an abstract class is used.
Now take a look at the API docs for Block class and near the top of page you can find "what that point is for" from the "list of known sub classes"
https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.18.2/net/minecraft/world/level/block/Block.html
Those are all bits and pieces that have unique properties and behaviours.
And at the bottom of the hierarchy where a class can be instantiated "new" here is an example API docs
https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.18.2/net/minecraft/world/level/block/DetectorRailBlock.html
There should be somewhere some proper Minecraft tutorial.
If you ever did make a new one you would extend from it to make a new one or cast type dependent if suitable.
It seems to be an enclosing static class wrapper but it has methods in its own level. However, it does contain static classes and those are simply called with their method to use , not instantiated new.
I need to use RegLoadKey function in my java code by using jna, but I'm getting the following error message:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'RegLoadKey': The specified procedure could not be found.
Blockquote
RegLoadKey syntax
LONG WINAPI RegLoadKey(
_In_ HKEY hKey,
_In_opt_ LPCTSTR lpSubKey,
_In_ LPCTSTR lpFile
);
my code:
Advapi32.java
import com.sun.jna.platform.win32.WinReg.HKEY;
import com.sun.jna.win32.StdCallLibrary;
public interface Advapi32 extends StdCallLibrary
{
long RegLoadKey(HKEY hKey, String lpSubKey,String lpFile);
}
apiTest.java
import com.sun.jna.*;
import com.sun.jna.platform.win32.WinReg.HKEY;
public class apiTest
{
public static void main (String [] args)
{
Advapi32 lib2 = (Advapi32) Native.loadLibrary("Advapi32", Advapi32.class);
HKEY key1 = new HKEY();
String filePath = "C:\\tmp\\software";
String regName = "loadedRegKey";
long test = lib2.RegLoadKey(key1, regName, filePath);
}
I think there are several problems with my code. I'm new to windows api and jna.
Did you know that an Advapi32 encapsulation is already part of JNA?
Have a look here. I just saw that your method RegLoadKey is not yet added there. So add it and submit that change to the jna guys. Afterwards you can use it like this (pseudo code):
public class RegistryRead{
private Advapi32 api = null;
public RegistryRead(){
this.api = Advapi32.INSTANCE;
}
public void read() {
long winapi = this.api.RegLoadKey(HKEY hkey, String subkey, String file);
...
}
}
If you look at the Advapi32 library mapping that comes with JNA, you'll see that the library instantiation includes some options to the load method. Among other things, these load options automatically map things like RegLoadKey to RegLoadKeyW, which is the real name of the function you're trying to link to.
It is a typical for JNA developing error. Just add before using it.
System.setProperty("jna.library.path","PATH_TO_LIBRARY_JNA");
PATH_TO_LIBRARY_JNA - absolute path to jna lib
I'm controlling some external device using my android app, and in order to control this device it provides an sdk which is a C#(.dll) files, I know how to load .dll libraries into java and how to use it, but I can't access a lot of methods inside these libraries because it takes C# native arguments like structs which is not available in Java, and I tried equivalents in Java like classes with public elements to represent a struct but it keeps give me the error: java.lang.IllegalArgumentException: Unsupported argument type
This is how I deal with the Library(using jna):
import outsource.classes.MyClass;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Test {
public interface simpleDLL extends Library {
long H264_DVR_GetLastError(int num); // accessed without any problems
boolean H264_DVR_SetDVRMessCallBack(MyClass obj, long num); // this "MyClass" is mainly a STRUCT in the C# sdk
}
static
{
System.loadLibrary("NetSdk");
}
public static void main(String args[]) {
simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary(("NetSdk"),
simpleDLL.class);
System.out.println(INSTANCE.H264_DVR_GetLastError(4));
System.out.println(INSTANCE.H264_DVR_SetDVRMessCallBack(new MyClass(),
0));
}
}
And this is how I created MyClass.Class:
public class MyClass() {
public String Id = "myDevice";
public String UserName = "admin";
public int password = 1234;
}// also tried declaring the values inside a constructor but nothing changed
and this is how the struct defined inside the sdk:
typedef struct _DEVICEINFO
{
char id[64];
char user[64];
int pw;
}DEVICEINFO,*LP_DEVICEINFO;
p.s. I know there are some ways to write an android app with C# code using VisualBasic(e.g vs-android) but that won't work in my case as the app is already written and running with java and it's pretty huge with a lot of other functionalists so it can't be rewritten.
I'd like to use native windows api function in my java class.
The function I am interested in is GetShortPathName.
http://msdn.microsoft.com/en-us/library/aa364989%28VS.85%29.aspx
I tried to use this - http://dolf.trieschnigg.nl/eightpointthree/eightpointthree.html
but in some conditions java crashes completely when I use it, so it is not the option for me.
The question is
Do I have to write code in e.g C, make DLL and then use that DLL in JNI/JNA?
Or maybe I somehow can access the system API in different way?
I will appreciate your comments.
If maybe you could post some code as the example I would be grateful.
...
I found the answer using JNA
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
public class Utils {
public static String GetShortPathName(String path) {
byte[] shortt = new byte[256];
//Call CKernel32 interface to execute GetShortPathNameA method
int a = CKernel32.INSTANCE.GetShortPathNameA(path, shortt, 256);
String shortPath = Native.toString(shortt);
return shortPath;
}
public interface CKernel32 extends Kernel32 {
CKernel32 INSTANCE = (CKernel32) Native.loadLibrary("kernel32", CKernel32.class);
int GetShortPathNameA(String LongName, byte[] ShortName, int BufferCount);
}
}
Thanks for hint. Following is my improved function. It uses Unicode version of the GetShortPathName
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
public static String GetShortPathName(String path) {
char[] result = new char[256];
Kernel32.INSTANCE.GetShortPathName(path, result, result.length);
return Native.toString(result);
}
New to JAVA and Netbeans
My problem is that when I try to call a method from another class I get error:
"Cannot find symbol"
I do have import in calling class and tried every variation I could think of but the same error continues.
I copied the method into the calling class and the error disappears, but this is not useful since many classes will need to call this function.
Here are the specifics:
Created a test method in:
Calculators
|--Source Packages
|--schmidtjts.com.calculators
|--Functions_Conversion.java
package schmidtjts.com.calculators;
public class Functions_Conversion {
public static int test_lf(int Input) {
return Input * 10;
}
)
And then try to call it in:
Calculators
|--Source Packages
|--schmidtjts.com.calculators.ui.pages
|--Displacement.java
package schmidtjts.com.calculators.ui.pages;
import schmidtjts.com.calculators.Functions_Conversion;
public class Displacement extends javax.swing.JPanel {
public Displacement() {
initComponents();
}
private void testMethod() {
double ttt = test_lf(1);
}
}
I hope someone will have an idea, I have searched many problems with similar descriptions but not found a solution.
Tried deleting cache and restarting Netbeans.
UPDATE:
Your code should look like this:
package schmidtjts.com.calculators.ui.pages;
//This import below isn't that relevant.
import schmidtjts.com.calculators.Functions_Conversion;
public class Displacement extends javax.swing.JPanel {
public Displacement() {
initComponents();
}
private void testMethod() {
//Initialize an object that can be used to call the method
Functions_Conversion myObject = new Functions_Conversion();
//Then call the method using the object you've just created
myObject.test_If(1);
}
}
ORIGINAL ANSWER:
Try initializing an object like this:
//Initialize an object that can be used to call the method
Functions_Conversion myObject = new Functions_Conversion();
//Then call the method using the object you've just created
myObject.test_If(1);