Valhalla Legends Forums Archive | Advanced Programming | calling a function via dllname and ordianal number using dll injection

AuthorMessageTime
thetempest
Hi,

i'm writing a patcher to load a dll into SC's address space. The problem is each time SC reloads, my dll has different entry addresses for all of its functions and SC crashes and burns because it can't call the dll fucntion. I'm using direct calling address. IE. call 0x00a00202

so my question is, in ASM i want to do this:
call test.dll@2 (call ordinal 2 outta the dll)

Thanks in advance
December 2, 2003, 1:37 AM
Skywing
[quote author=thetempest link=board=23;threadid=4005;start=0#msg33071 date=1070329069]
Hi,

i'm writing a patcher to load a dll into SC's address space. The problem is each time SC reloads, my dll has different entry addresses for all of its functions and SC crashes and burns because it can't call the dll fucntion. I'm using direct calling address. IE. call 0x00a00202

so my question is, in ASM i want to do this:
call test.dll@2 (call ordinal 2 outta the dll)

Thanks in advance
[/quote]
Rebase your DLL so that it doesn't conflict with something else. The default base address 0x10000000 is likely to force you to get rebased.

Try calling GetProcAddress (a documented, named export of Kernel32.dll) or writing your own PE header parser to grab the exported function address.

Without more detailed information, I can't give you more precise advice.
December 2, 2003, 1:56 AM
thetempest
hey,

well here is the deal, how do i set my own address? that would be GREAT, base addy for my DLL i mean. 2ndly i want my patcher to be able to right a call blahblah in ASM to handle the variables.

anyways, i'm still intrested in calling my functions via dllname@ordinalNumber...

thanks
December 2, 2003, 2:35 AM
Skywing
[quote author=thetempest link=board=23;threadid=4005;start=0#msg33087 date=1070332558]
hey,

well here is the deal, how do i set my own address? that would be GREAT, base addy for my DLL i mean. 2ndly i want my patcher to be able to right a call blahblah in ASM to handle the variables.

anyways, i'm still intrested in calling my functions via dllname@ordinalNumber...

thanks
[/quote]
The base address for your dll is the first argument to your DllMain function.
December 2, 2003, 2:47 AM
thetempest
hummm???

what do you mean, ya hModuel is the 1st arguemt, but how do i "set" that?

ok, another idea i had was this (but yours is FAR easier)

i want to store the addy of the function into static memory :)
EDIT:
[code]
call [004e5400] //function @1
call [004e5404] //function @2
[/code]

my only questions are:
1) How to do this using GetProcAddress() which returns a _cdelc or something (i need a DWORD)...
2) Storing the DWORD into memory

PROBLEM:
I know ASM, but MSVC++ is giving me SHIT!!!


[code]
//globals
__declspec( dllexport ) void _stdcall dontDropMe();
typedef void (*MYPROC)(void);
fstream file;

file.open("test.log",ios::in | ios:: out);

//inside function to store dynamic values in static address
HINSTANCE hwnd = GetModuelHandle("test2.dll");
dontdropme = (MYPROC) GetProcAddress(hwnd,"?dontDropMe@@YGXXZ");
file << dontdropme << "\n" << flush;
//this outputs 0x00a0020F (which is what i want to store into memory)

_asm
{
mov dword ptr [004e5400],dontdropme
}

[/code]


ERRORS:

1) it needs a 0x inside the [] for MSVC++ to regonize address
2) it says that the "ptr" is invalid
3) it says the [] are invalid
4) it says dontdropme is invalid datatype (i've even tried casting it to DWORD) no avail, i've even tried puting DWORD into EAX,EBX and doing [eax],address STILL doesn't work

any ideas please
thx
December 2, 2003, 2:56 AM
Skywing
You're running into a known MASM limitation. Try this...

[code]
__asm {
mov eax, 0x004e5400
mov dword ptr [eax], OFFSET dontdropme
}
[/code]
December 2, 2003, 2:59 AM
thetempest
[quote]
[code]
__asm {
mov eax, 0x004e5400
mov dword ptr [eax], OFFSET dontdropme
}
[/code]
[/quote]


"mov dword ptr [eax], OFFSET dontdropme" generates an error:
"improper operand type"
December 2, 2003, 3:03 AM
Skywing
[quote author=thetempest link=board=23;threadid=4005;start=0#msg33094 date=1070334208]
[quote]
[code]
__asm {
mov eax, 0x004e5400
mov dword ptr [eax], OFFSET dontdropme
}
[/code]
[/quote]


"mov dword ptr [eax], OFFSET dontdropme" generates an error:
"improper operand type"
[/quote]
If it's a stack variable, you need to do something like..

[code]__asm {
; include code from above except the last line...
mov ecx, dontdropme
mov dword ptr [eax], ecx
}[/code]
This is because a reference to dontdropme will implicitly require referencing a value stored on esp or ebp, and you can't do mov dword ptr [eax], dword ptr [esp+something].
December 2, 2003, 3:07 AM
thetempest
thanks,

finaly...UP THE KARMA =)

thanks again skywing ;D
December 2, 2003, 3:10 AM
thetempest
ack,

runtime problem:

when the game executes the:
[code]
mov dword ptr [eax],ecx
[/code]

it generates an NT_ACCESS_VIOLATION.

i've even tried suspending the thread, virtualallocex with page mem commit and rewrite and execute and then resuming...

nothing?

any ideas skywing?
December 2, 2003, 3:33 AM
Skywing
[quote author=thetempest link=board=23;threadid=4005;start=0#msg33116 date=1070335981]
ack,

runtime problem:

when the game executes the:
[code]
mov dword ptr [eax],ecx
[/code]

it generates an NT_ACCESS_VIOLATION.

i've even tried suspending the thread, virtualallocex with page mem commit and rewrite and execute and then resuming...

nothing?

any ideas skywing?
[/quote]
If you are writing to a code address you will have to VirtualProtect(Ex) it to something that grants write access (it'll probably be PAGE_EXECUTE_READONLY by default). VirtualAlloc(Ex)'ing over it will not work.
December 2, 2003, 3:46 AM
thetempest
great,

thanks. I just copy/pasted didn't even think about the ProtectEx()...

thanks again
December 2, 2003, 3:55 AM
Adron
But instead of
[code]
//inside function to store dynamic values in static address
HINSTANCE hwnd = GetModuelHandle("test2.dll");
dontdropme = (MYPROC) GetProcAddress(hwnd,"?dontDropMe@@YGXXZ");
file << dontdropme << "\n" << flush;
//this outputs 0x00a0020F (which is what i want to store into memory)

_asm
{
mov dword ptr [004e5400],dontdropme
}
[/code]

use

[code]
//inside function to store dynamic values in static address
HINSTANCE hwnd = GetModuelHandle("test2.dll");
dontdropme = (MYPROC) GetProcAddress(hwnd,"?dontDropMe@@YGXXZ");
file << dontdropme << "\n" << flush;
//this outputs 0x00a0020F (which is what i want to store into memory)

*(MYPROC*)0x4e5400 = dontdropme;
[/code]


You don't need assembler to write to a pointer in C/C++!
December 2, 2003, 10:13 AM
Kp
[quote author=thetempest link=board=23;threadid=4005;start=0#msg33087 date=1070332558]
well here is the deal, how do i set my own address? that would be GREAT, base addy for my DLL i mean. 2ndly i want my patcher to be able to right a call blahblah in ASM to handle the variables.

anyways, i'm still intrested in calling my functions via dllname@ordinalNumber...[/quote]

There's two ways to set your address. The first is to do it at link time with a switch to your linker. If you're using VC6, go to Project->Settings->Link tab. Category: Output. Base address: set this to the base you want. Note that the lowermost bits will need to be zero to work right (the linker should catch it if you try to set them nonzero, but it'll likely complain at you if you try it).

The second way to do this is to use rebase.exe, which comes with VC. Rebase can change the disk image of a DLL to have a new base after you've built it; although I've never tried, I suspect you could rebase other people's DLLs without the source, as long as the DLL relocation information was still embedded (and without the relocation info, a load will simply fail if the DLL is assigned to an in-use address).
December 2, 2003, 11:22 PM
Adron
Yes, you can rebase other people's dlls without source. You can do that yourself for dlls in your system directory.
December 2, 2003, 11:36 PM

Search