• Welcome to Valhalla Legends Archive.
 

Using offsets found in w32dasm

Started by Maddox, January 29, 2004, 07:40 PM

Previous topic - Next topic

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.
asdf.

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.

Maddox

#2
Quote from: Skywing on January 29, 2004, 08:57 PM
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.

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?


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))
asdf.

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.

Skywing

Quote from: Adron on January 30, 2004, 05:24 PM
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.
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..

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?

Maddox

#6
Quote from: Skywing on January 30, 2004, 06:26 PM
Quote from: Adron on January 30, 2004, 05:24 PM
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.
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..

I think that is shown here. Oh, by the way Skywing the code you posted won't work with the variable "offset."

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);
}
asdf.

Skywing

It will work if you use an unsigned long instead of a const unsigned long.

Maddox

#8
Quote from: Skywing on January 30, 2004, 08:21 PM
It will work if you use an unsigned long instead of a const unsigned long.

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 ']'."
asdf.

Skywing

Quote from: Maddox on January 30, 2004, 08:42 PM
Quote from: Skywing on January 30, 2004, 08:21 PM
It will work if you use an unsigned long instead of a const unsigned long.

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 ']'."
Oh; that's not exactly something hard to fix.  You don't have to use that variable name.