Get Functions from DLL
Get Functions from DLL
with your madKernel it's possible to get the exports from any dll.
Is it somehow possible to get also the parameters of function, the types and the calling convention?
Every parameter is a DWORD. Everytime!
Code: Select all
004033B4 /$ 55 PUSH EBP
004033B5 |. 8BEC MOV EBP,ESP
004033B7 |. 5D POP EBP
004033B8 \. C2 1400 RETN 14
0040342C . 6A 05 PUSH 5 ; /Arg5 = 00000005
0040342E . 6A 04 PUSH 4 ; |Arg4 = 00000004
00403430 . 6A 03 PUSH 3 ; |Arg3 = 00000003
00403432 . 6A 02 PUSH 2 ; |Arg2 = 00000002
00403434 . 6A 01 PUSH 1 ; |Arg1 = 00000001
00403436 . E8 79FFFFFF CALL bla.004033B4 ; \bla.004033B4
coutn of params = ret value div 4
for example: 0x14 div 4 = 20 div 4 = 5
Code: Select all
004033B4 /$ 55 PUSH EBP
004033B5 |. 8BEC MOV EBP,ESP
004033B7 |. 5D POP EBP
004033B8 \. C3 RETN
0040342C . 6A 05 PUSH 5 ; /Arg5 = 00000005
0040342E . 6A 04 PUSH 4 ; |Arg4 = 00000004
00403430 . 6A 03 PUSH 3 ; |Arg3 = 00000003
00403432 . 6A 02 PUSH 2 ; |Arg2 = 00000002
00403434 . 6A 01 PUSH 1 ; |Arg1 = 00000001
00403436 . E8 79FFFFFF CALL bla.004033B4 ; \bla.004033B4
0040343B . 83C4 14 ADD ESP,14
paramcount = ESP value div 4
example: ESP value = 0x14 div 4 = 20 div 4 = 5
Code: Select all
004033B4 /$ 55 PUSH EBP
004033B5 |. 8BEC MOV EBP,ESP
004033B7 |. 5D POP EBP
004033B8 \. C2 0800 RETN 8
0040342C . 6A 04 PUSH 4 ; /Arg2 = 00000004
0040342E . 6A 05 PUSH 5 ; |Arg1 = 00000005
00403430 . B9 03000000 MOV ECX,3 ; |
00403435 . BA 02000000 MOV EDX,2 ; |
0040343A . B8 01000000 MOV EAX,1 ; |
0040343F . E8 70FFFFFF CALL bla.004033B4 ; \bla.004033B4
the count of params is:
nothing used (not MOV EAX before call) = 0
EAX used = +1; MOV EAX, .... call
EDX used = +1; MOV EDX, ... call
ECX used = +1; MOV ECX, ... call
for every PUSH = +1 or better (ret value div 4)
for the example above:
EAX is used (B8 01000000 MOV EAX,1) = 1
EDX is uded (BA 02000000 MOV EDX,2) = 1
ECX is uded (B9 03000000 MOV ECX,3) = 1
RET 8 = 8 / 4 = 2
-> 1+1+1+2 = 5 calling conversion (becasue of MOV EAX, ...) -> register
if you have a function like that:
Code: Select all
GetProcAddress(dwHandle: DWord; pProcName: PChar); stdcall;
Code: Select all
GPA:
....
RET 8
PUSH pProcName
PUSH dwHandle
CALL GPA
BUT you can use this for hooking:
Code: Select all
GPACallback(a,b : DWord); stdcall;
If somebody is interested in it.
Unfortunately I don't know, how to geht the disassembly of the function calls you posted above....
how do I get these using Delphi?
that would be great, some source with comments would be wonderful tooMaybe i can write a simple program which creates the header like that. oO
If somebody is interested in it.
neji, i have done the disassembling with OllyDbg, but i think madDisAsm should do the same.
You need a program which is using this function. Then u must disassemble it (for RET value checking) and a call of it (ADD ESP, MOV EAX...)
You can do this by hooking the function and looking for the return address to get the call of the function.
Its a little bit tricky.
But if you only have the library (and no program which is using it) you cann do the following:
if it has a PUSH EBP an begining it is 99% cdecl or stdcall convention. So if there is no PUSH EBP -> should be register. THen its hard to see if it has more 0-3 params. If it hast 4 params the RET value is >= 0.
(See the posts above)
The differnce between cdecl and stdcall:
if there is pushed the ebp register at first and then it is used in the code
ex. (MOV EAX, [EBP+8]) then it is a parameter. If the RET value is != 0 then its stdcall convention: RET value div 4 = paramcount.
If the ret value is 0 it can be a stcall vonvention with 0 params or cdecl.
So if (EBP+XXX) is inside the code and RET = 0 then its cdecl convention.
You then need to get the highest EBP value (XXX) subtract 4 and divide it by 4: (XXX-4) div 4. Then you get the paramcount.
Its all a little bit tricky but it works for 90% of functions. All you need is madDisAsm.
Maybe i find some time on weekend for creating an example and looking for win64 convention.
( http://www.freepascal.org/wiki/index.ph ... /AMD64_API ) oO
Code: Select all
0049c634 public Unit1.mooh: ; function entry point
0049c634 56 mov ecx, $49c654 ; 'asdf'
0049c639 mov edx, $49c654 ; 'asdf'
0049c63e mov eax, [$4a3ddc]
0049c643 call -$84 ($49c5c4) ; Unit1.TForm1.foo2
0049c643
0049c648 57 ret
and where do I get the Returnadress there?
function mooh (0049c634)
function foo2 (0049c5c4)
You can only say 99% what foo2 lookes like. As you has said before, it hast register convention (eax, ebx, ecx is used). And it has 2 params (eax, ebx, ecx, where EAX the first , EBX the second and ECX the third:
We have:
Code: Select all
function foo2(a,b,c: DWord): DWord;
begin
//
end;
Code: Select all
procedure foo2(a,b,c: DWord);
begin
//
end;
Code: Select all
procedure foo2(a: DWord; b,c: DWord);
begin
//
end;
Code: Select all
procedure foo2(a: Dword; b,c: PChar);
begin
//
end;
1) register convention with < 4 parms
2) cdecl convention
3) stdcall convention with no params
as we can see there is no PUSH EBP at first it seems to be a register convention
because there is NO register used inside the function it has no params
Code: Select all
procedure mooh;
begin
end;
Code: Select all
procedure mooh; stcall;
begin
end;
Code: Select all
procedude moog; cdecl;
begin
end;
if we now put all togehter:
Code: Select all
const text = 'asdf';
var global: Dword; // or other type
procedure foo2(a: Dword; b,c: PChar);
begin
//
end;
procedure mooh;
begin
foo2(global,text,text);
end;
because of the Unit1, Tform1 you can see that it is compiled by Borland Delphi XXX
Borland Delphi is using the register convention. That means:
Code: Select all
procedure foo3(a: Dword; b,c: Integer; f: Single);
Code: Select all
procedure foo3(a: Dword; b,c: Integer; f: Single);
Code: Select all
procedure foo3(a: Dword; b,c: Integer; f: Single); stdcall;
Hook the export address with this function:
Code: Select all
var ReturnAddress: DWord;
procedure myCallbackofExportedFunction;
begin
asm
PUSH [ESP]
POP DWORD PTR [ReturnAddress]
end;
UnhookTheExportedFunction;
CreateDisassemblingAndSaveIt(TheExportedFunction);
CreateDisassemblingAndSaveIt(Pointer(DWord(ReturnAddress)-100));
ExitProcess(0);
end;
if you have a call then the ReturnAddress is on the stack. We get it from there. Now we unhook the function (because there is a jump in there) Its not needed, but we then know if there is a PUSH EBP or something interesting in the first 5/6 bytes.
We disassemble the function (it must be uncrypted now) -> then we can analyse it later.
We disassemble the function which is calling oru fucntion (is inside the executable or other dll which is using the export which we want to analyse)
It is uncrypted, too. We need to analyse it.
I hope this will help you a little bit :>
But I still have some questions
in my example foo1 is declared like this :
Code: Select all
procedure foo1(a,b : string);
When a Function is called, the Returnadress is on the stack right? How can I get this adress using Delphi?
Code: Select all
procedure foo1(a,b : string);
you wrote an disassembling with 'foo2' (not 'foo1')
i have tested you code
Code: Select all
procedure foo1(a,b : string);
Set a Breakpoint when you are calling it and if it breaks press Crt+Alt+C
Then u see that a,b: string is only using 2 params.
Delphi is using PUSH EBP inside a register call when you use String as param or result. So its not that easy to see the convention, if you dont have the call.
Delphi7:
http://uall.overclock.ch/neji_stringasparam.jpg
Delphi is using 3 params.
The first is the Object!
If you want to hook it you need these 3 params, not the 2 that you used in Delphi.
if you want to hook
Code: Select all
procedure TForm1.Foo1(a,b : string);
begin
end;
Code: Select all
procedure Foo1(object: DWord; a,b : string);
begin
end;
But if the function is used inside an object, delphi creates a function with 3 params, where the first is the object. Now if you want to hook this function in a library you need exaclty the same paramcount. An this is 3 NOT 2.
http://uall.overclock.ch/neji_objectprocedure.jpg