Valhalla Legends Forums Archive | General Programming | Using offsets found in w32dasm

AuthorMessageTime
Maddox
Once I've found an offset I would like to call to such as 6fb1c950h how do I go about converting the offset into something useful I can use in either inline ASM or a function pointer?

If I try to call 0x6fb1c950 using inline ASM it gives me a improper operand type. Is this because the call isn't relative? Do I need to get the RVA and how is this done? Do I simply subtract the base address from the found address?

A lot of questions I know, but any help is appreciated.
January 30, 2004, 1:40 AM
Skywing
Two simple ways to do this with inline ASM if you're using VC:

const unsigned long offset = 0x6fb1c950; // D2Client!someguithting

__asm call dword ptr [offset] // option one

__asm mov eax, 0x6fb1c950
__asm call eax // option two

I suppose you could use _emit too.
January 30, 2004, 2:57 AM
Maddox
[quote author=Skywing link=board=5;threadid=4996;start=0#msg41778 date=1075431451]
Two simple ways to do this with inline ASM if you're using VC:

const unsigned long offset = 0x6fb1c950; // D2Client!someguithting

__asm call dword ptr [offset] // option one

__asm mov eax, 0x6fb1c950
__asm call eax // option two

I suppose you could use _emit too.
[/quote]

Ah thanks, seems obvious to me now, however, I still have some confusions to clear up.

When maphack creates a pointer to an ingame variable or function it uses the following macro to get the address. The address it passes to the macro is similiar to the one I just posted. What purpose does this macro serve and should I be using something similiar?

[code]
enum {DLLNO_D2CLIENT, DLLNO_D2COMMON, DLLNO_D2GFX, DLLNO_D2WIN, DLLNO_D2LANG, DLLNO_D2CMP};

enum {
   DLLBASE_D2CLIENT = 0x6FAA0000,
   DLLBASE_D2COMMON = 0x6FD40000,
   DLLBASE_D2GFX = 0x6FA70000,
   DLLBASE_D2WIN = 0x6F8A0000,
   DLLBASE_D2LANG = 0x6FC10000,
   DLLBASE_D2CMP = 0x6FDF0000,
};

#define DLLOFFSET(a1,b1) ((DLLNO_##a1)|(( ((b1)<0)?(b1):(b1)-DLLBASE_##a1 )<<8))
[/code]
January 30, 2004, 3:09 AM
Adron
I think that macro serves the purpose of allowing you to call functions that aren't at a fixed offset. The D2 dlls tend to be loaded at different base addresses each time, so you need to calculate the correct offset.
January 30, 2004, 11:24 PM
Skywing
[quote author=Adron link=board=5;threadid=4996;start=0#msg41877 date=1075505043]
I think that macro serves the purpose of allowing you to call functions that aren't at a fixed offset. The D2 dlls tend to be loaded at different base addresses each time, so you need to calculate the correct offset.
[/quote]The problem is that method hardcodes the bases anyway. It wouldn't be difficult to modify the macro to lookup to some global variable set to the dll base at runtime though..
January 31, 2004, 12:26 AM
Adron
Hmm, I thought it'd look up the current base offset later from the DLLNO_ thing that gets put into the low order byte?
January 31, 2004, 12:29 AM
Maddox
[quote author=Skywing link=board=5;threadid=4996;start=0#msg41895 date=1075508787]
[quote author=Adron link=board=5;threadid=4996;start=0#msg41877 date=1075505043]
I think that macro serves the purpose of allowing you to call functions that aren't at a fixed offset. The D2 dlls tend to be loaded at different base addresses each time, so you need to calculate the correct offset.
[/quote]The problem is that method hardcodes the bases anyway. It wouldn't be difficult to modify the macro to lookup to some global variable set to the dll base at runtime though..
[/quote]

I think that is shown here. Oh, by the way Skywing the code you posted won't work with the variable "offset."
[code]
DWORD GetDllOffset(char *dll, int offset)
{
   HMODULE hmod = GetModuleHandle(dll);
   if (!hmod) hmod = LoadLibrary(dll);
   if (!hmod) return 0;
   if (offset < 0) {
      return (DWORD)GetProcAddress(hmod, (LPCSTR)-offset);
   }
   return ((DWORD)hmod)+offset;
}

DWORD GetDllOffset(int num)
{
   static char *dlls[] = {"D2CLIENT.DLL", "D2COMMON.DLL", "D2GFX.DLL", "D2WIN.DLL", "D2LANG.DLL", "D2CMP.DLL"};
   return GetDllOffset(dlls[num&0xff], num>>8);
}
[/code]
January 31, 2004, 1:55 AM
Skywing
It will work if you use an unsigned long instead of a const unsigned long.
January 31, 2004, 2:21 AM
Maddox
[quote author=Skywing link=board=5;threadid=4996;start=0#msg41915 date=1075515685]
It will work if you use an unsigned long instead of a const unsigned long.
[/quote]

Not in Visual Studio 6.0, "offset" is a command in the assembler's inline asm. You can't use it as a variable at all, no matter what the type is.

On compile it gives the error "inline assembler syntax error in 'first operand'; found ']'."
January 31, 2004, 2:42 AM
Skywing
[quote author=Maddox link=board=5;threadid=4996;start=0#msg41917 date=1075516959]
[quote author=Skywing link=board=5;threadid=4996;start=0#msg41915 date=1075515685]
It will work if you use an unsigned long instead of a const unsigned long.
[/quote]

Not in Visual Studio 6.0, "offset" is a command in the assembler's inline asm. You can't use it as a variable at all, no matter what the type is.

On compile it gives the error "inline assembler syntax error in 'first operand'; found ']'."
[/quote]
Oh; that's not exactly something hard to fix. You don't have to use that variable name.
January 31, 2004, 3:31 AM

Search