Log in

View Full Version : GetProcAddress by ordinal problem


mike
November 29th, 2002, 06:10
I'm trying to write some thunk code in C, but I'm having trouble loading some of the undocumented functions from kernel32 by ordinal:

I want to load LoadLibrary16 (35), FreeLibrary16 (36), and GetProcAddress16 (37). I tried using
Code:

typedef HANDLE (__cdecl *LL16)(char *);
static LL16 LoadLibrary16 = NULL;
static HANDLE hKernel;
...
hKernel = GetModuleHandle("KERNEL32";
LoadLibrary16 = (LL16)GetProcAddress(hKernel, (LPCSTR)35);


But it always fails. Am I doing that wrong?
I forced it to work by adding the offset (0x2AF46) to hKernel and casting it into a function.

I'm also looking for a 16-bit version of GetModuleFileName. Does GetModuleFileNameA work?

Solomon
November 29th, 2002, 09:47
the highest bit of your ordinal should be 1?

mike
November 30th, 2002, 05:32
Quote:
the highest bit of your ordinal should be 1?
Huh? like 0x80000023 instead of 35? Is that documented somewhere?

From MSDN:

GetProcAddress

The GetProcAddress function retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).


FARPROC GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);

Parameters

- hModule
[in] Handle to the DLL module that contains the function or variable. The LoadLibrary or GetModuleHandle function returns this handle.

- lpProcName
[in] Pointer to a null-terminated string that specifies the function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.

Solomon
November 30th, 2002, 06:45
Oops, what I said is wrong. sorry

dion
November 30th, 2002, 08:44
interesting... mike,
you type the documentation:

FARPROC GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);

and you type in your code:

GetProcAddress(hKernel, (LPCSTR)35);

but i can be wrong here... is it true that 35 can be refered as lpProcName? would it be KERNEL32.35 or somewhat? i dont know this, because i have problem to with 16bit dll imports. maybe someone will explain this one.

regards

bart
November 30th, 2002, 15:04
.386
.model flat,stdcall
extrn LoadLibraryA roc
extrn MessageBoxA roc
.data
szK32 db 'KERNEL32',0

.code
start:
int 3

push offset szK32
call LoadLibraryA

; ordinal number
mov ecx,9


and ecx,0fffffffh ;EAX=Ordinal Nr. (np. 80000001)
push ecx ;

mov edx,[eax+3Ch] ;
add eax,edx ;
mov ecx,[eax+34h] ;
mov esi,[eax+78h] ;
pop eax ;
add esi,ecx ;
mov edx,[esi+1ch] ;
sub eax,[esi+10h] ;
add edx,ecx ;
mov eax,[eax*4+edx] ;
add eax,ecx ; EAX = ordinal address

; call api
push 21004Ch
call eax

ret
end start

dELTA
November 30th, 2002, 19:05
I'm not sure about those exact undocumented API:s that you are trying to access, but I do know that after the first version of Windows 95, Microsoft added protection code so that many undocumented API:s could only be loaded from certain known operating system processes. You will find more info about this in Pietrek's "Windows 95 System Programming Secrets".

mike
December 1st, 2002, 22:20
Looks like you avoid GetProcAddress entirely here. Does this traverse a table in the DLL or something?
Quote:
Originally posted by bart
.386
.model flat,stdcall
extrn LoadLibraryA roc
extrn MessageBoxA roc
.data
szK32 db 'KERNEL32',0

.code
start:
int 3

push offset szK32
call LoadLibraryA

; ordinal number
mov ecx,9


and ecx,0fffffffh ;EAX=Ordinal Nr. (np. 80000001)
push ecx ;

mov edx,[eax+3Ch] ;
add eax,edx ;
mov ecx,[eax+34h] ;
mov esi,[eax+78h] ;
pop eax ;
add esi,ecx ;
mov edx,[esi+1ch] ;
sub eax,[esi+10h] ;
add edx,ecx ;
mov eax,[eax*4+edx] ;
add eax,ecx ; EAX = ordinal address

; call api
push 21004Ch
call eax

ret
end start

Kayaker
December 2nd, 2002, 06:20
Hi All

This is interesting, creating your own .lib file as Peitrek outlines in Win95 Secrets, as dELTA mentioned (see Appendix A) seems to be the elegant way to go. You create a .def file with the undocumented kernel functions you want to include and use the VC++ 'lib' function to compile a .lib file.

He provides a version of the K32lib.lib and K32lib.def files in the source and I'll up them here if anyone wants to try it. From the docs:

To use K32LIB.LIB in your project, you should place it immediately after
KERNEL32.LIB in the list of import libraries. This forces the Microsoft linker
to place the code and data from K32LIB.LIB contiguous with the code
and data brought in from KERNEL32.LIB. You'll see two references to
KERNEL32.DLL in the resulting executable. Don't be too concerned,
though. You're getting two IMAGE_IMPORT_DESCRIPTOR headers
for KERNEL32.DLL, but not two copies of all the data that describes
each imported function.

Borland C++ users can take K32LIB.DEF and run it through IMPORT. LIB
to create an import library in the proper format for TLINK. The command line
in this case is:
IMPLIB K32LIB.LIB K32LIB.DEF
You can place K32LIB.LIB anywhere in the import library list; TLINK
doesn't care about the order in which it appears.

For MASM I think you can use the L2EXTIA.EXE provided in Hutches Masm32. It successfully created an inc file in EXTERNDEF format, but I haven't tested out its use yet.


The K32lib.def file Peitrek uses doesn't have any newer undocumented functions (he lists 100 while my Win98SE kernel has 122), but it should have what you need. i.e. it lists
LoadLibrary16@4 @35
FreeLibrary16@4 @36
GetProcAddress16@8 @37


If you want to roll your own GetProcAddress function, Iczelion's PE tut #7 Export Table will explain how to walk the export directory of kernel32 as bart did, accessing the IMAGE_EXPORT_DIRECTORY and AddressOfNameOrdinal array.

The other option if this is just a one-shot deal on your own system, is to get the address directly using IDA (a little idc scripting project to create a .def file perhaps? ;-)

Let us know if the K32lib.lib file works if you decide to use it. I think I'm off to try it in Masm ;-)

Regards,
Kayaker

mike
December 2nd, 2002, 20:48
Kayaker wrote:
Quote:
The other option if this is just a one-shot deal on your own system, is to get the address directly using IDA
Yup. That's what I meant when I wrote
Quote:
I forced it to work by adding the offset (0x2AF46) to hKernel and casting it into a function.
How many different versions of Kernel32 are there?
Bart-thanks for the code snippet; Kayaker-thanks for the pointers & zip. They look like just what I need.

Lots of references to Pietrek's stuff; is it available online anywhere?

ZaiRoN
December 2nd, 2002, 21:08
Hi.
try here:
http://www.wheaty.net/

ZaiRoN

mike
December 3rd, 2002, 01:41
Zairon- I've seen his homepage. I was wondering if anyone had put his now out-of-print book online, or at least could quote me some relatively unique text from the middle of the book for doing a search myself

Kayaker
December 3rd, 2002, 03:42
I tested out thunking down to Win16 and it worked out OK. For Masm you need to create an inc file from the K32lib.lib file with L2extia.exe and include them both. As for making use of the returned address from GetProcAddress16, calling QT_Thunk directly seems to be the way to go to call a 16 bit dll. For a good example of how it all fits together check out

Direct Thunking in Windows 95
Using undocumented calls to bypass the thunk compiler - Matt Pietrek
http://www.ddj.com/documents/s=952/ddj9614c/9614c.htm

From the doc:
Calling QT_Thunk in your code requires you to do two things. First, you have to put the 16:16 address to call into the EDX register. Second, the code from which you're calling QT_Thunk should have an EBP stack frame set up, and at least 0x3C bytes of local storage that you're not relying on. This unusual step is required because QT_Thunk builds its convoluted stack frame for calling the 16-bit code in the region below where the EBP register points to.

Following his example I was able to call directly the 16 bit MESSAGEBEEP function of User.exe. Not too exciting a thing to do with the technique but at least the feedback was immediate
Here's the pertinent code:

Code:

include k32lib.inc
includelib k32lib.lib

KernelDllName db "Kernel32.dll", 0
QT_Thunk db "QT_Thunk", 0
User16Exe db "User.exe",0
MessageBeep16 db "MESSAGEBEEP",0

hLib HANDLE ?
hLib16 HANDLE ?
pQT_Thunk DWORD ?
pMessageBeep16 DWORD ?

;=================Thunk16===========
Thunk16 proc

; Set up a stack frame as suggested by Pietrek
push ebp
mov ebp, esp
sub esp, 3Ch

invoke LoadLibrary, ADDR KernelDllName
mov hLib, eax
invoke GetProcAddress, eax, ADDR QT_Thunk
mov pQT_Thunk, eax

invoke LoadLibrary16, ADDR User16Exe
mov hLib16, eax
invoke GetProcAddress16, eax, ADDR MessageBeep16
mov pMessageBeep16, eax


push MB_OK
mov edx, [pMessageBeep16]
call pQT_Thunk

invoke FreeLibrary16, hLib16
invoke FreeLibrary, hLib

mov esp, ebp
pop ebp

ret
Thunk16 endp
;===============END Thunk16==========

Great fun. Now maybe I'll call the User.exe function BOZOSLIVEHERE and see what it actually does ;p

Kayaker

PS Mike. I think the Ebook is at his home page if you check under Downloads. It's also on the RCE CD which is now available for d/l.

mike
December 3rd, 2002, 04:02
Quote:
PS Mike. I think the Ebook is at his home page if you check under Downloads. It's also on the RCE CD which is now available for d/l.
Only the code is available on his download page, none of the explanation. As for the RCE CD, I'd pay someone for a copy, but I'm on dialup, so no chance of downloading it.
Quote:
As for making use of the returned address from GetProcAddress16...
I'm already doing that, so no worries there.

Kayaker
December 3rd, 2002, 18:33
Quote:
Originally posted by mike
Only the code is available on his download page, none of the explanation. As for the RCE CD, I'd pay someone for a copy, but I'm on dialup, so no chance of downloading it.


Well I'll be, there's no book in the RCE CD either, just the code examples. Am I the only one with the full pdf file? No idea where I picked it up but since it exists I'm sure you can find it. Perhaps I can add it to the archives if it seems too difficult to find.

ZaiRoN
December 3rd, 2002, 20:00
Hi.
Quote:
I can add it to the archives
There is not need Kayaker:
http://www.dore.ru/library/windows/PietrekBook.pdf

ZaiRoN

Aimless
December 4th, 2002, 10:12
Post me a site where I can upload the electronic book in PDF format

Have Phun,