Archphase, you can "sub eax, 4096" instead of "dec eax" in the base-scanning loop.

telophase, once you have the k32 imagebase, you can use your own manual "GetProcAddress" to find LoadLibrary in kernel32, and from there on you can get any DLL + export you want. Do note that there's a lot of things to handle in GetProcAddress, like ordinals and NT forwarded exports, and you ought to use binary search to speed up the process, etc.
Posted on 2004-04-15 00:29:48 by f0dder
Try teh following (by lingo i think)


mov eax,fs:[30h]
mov edx,0B8h
mov ecx,[eax+30h]
test eax,eax
jns KI_1
mov ebx,[eax+34h]
or ecx,ecx
jnz KI_2
KI_1:
mov eax,[eax+0Ch]
sub edx,0B0h
mov eax,[eax+1Ch]
mov ebx,[eax]
KI_2:
mov eax,[ebx+edx] ;;eax = kernel32.dll
Posted on 2004-04-15 03:59:47 by roticv
Wooh, "magic code" :) - such code should have some comment of what it does and why it works... not everybody has the TIB memorized ;)
Posted on 2004-04-15 04:04:08 by f0dder
well the exe returns to kernel32.dll so there will be a return address in stack

so mov eax,
and eax,0fff <----- masking some bits i dont remember if i am right with mask but it gotta be masked

sub eax,1000

cmp ,0x5a4d Mz header
then from there +3c blah blah blah then parse the export table of kernel32 for loadlib and getproc
then loadlib any dll and get proc any address and call any function

this example i think i saw in win32asm.cjb (iczelions site) i think the proggys name is kernel32 or some thing similar and i think the author name is y0da

if it snt avl i think i have it some where in my hd

ill upload it if some one wants it

regards
Posted on 2004-04-15 10:12:52 by bluffer
That and won't do much good :). The idea is to mask off the lower bits, effectively aligning the address to 4k. This works because all page allocations on x86 are done on at least 4k boundaries - some would argue that you can even align to 64k since images are always loaded to 64k boundaries... but it's safer only aligning to 4k, and the scanning is fast enough anyway.

Here's some code to do it (normally of course wrapped in a SEH, but I opted for simplicity this time):


and eax, 0fffff000h ; mask off lower bits: imagebase is a multiple of 4k
@@find_base_loop:
cmp word ptr [eax], 05A4Dh ; 'MZ' - dos exe signature
jz @@good_os
sub eax, 1000h ; scan down in decrements of 1000h
jmp short @@find_base_loop
Posted on 2004-04-15 10:21:13 by f0dder
Hmm... but it might cause some unneeded disk accesses if some pages are swapped out.

In an API monitoring program I was making for 9X earlier I have:


...
mov esi,[esi+4] ; ESP passed from Ring3 part
ksearch:
dec esi
xor si,si
cmp word [esi],'MZ'
jnz ksearch
...

Erm... But then I'm searching forward for some code locations to be patched anyway, so I guess it doesn't make too much of a difference :P
Posted on 2004-04-15 15:51:10 by Sephiroth3

The and thread-return values are different on my system...

As a consolation (to myself) I wasn't so wrong after all :grin:
The return values appear to be different always. However, under some OS versions you could end a program with a RET instead of ExitProcess.
Funny: just tried your test program under ME, it gives me a "ret"value of zero... :confused:
Posted on 2004-04-15 16:28:05 by QvasiModo

Hmm... but it might cause some unneeded disk accesses if some pages are swapped out.

Kernel32 swapped out? Not very likely unless some *very* memory-hungry application has been run - and then the whole system performance is going to suck anyway. (Btw: DisablePagingExecutive on NT when you have >=256 megs of ram, it's nice).


In an API monitoring program I was making for 9X earlier I have:

That code seems silly. And by 0xFFFF0000h and dec by 0000010000h instead. (And again, 4k is safer and quite fast enough).


Funny: just tried your test program under ME, it gives me a "ret"value of zero...

That's pretty weird - I probably messed something up bigtime :-s. Have you tested (in a debugger) what a "RET" in a threadproc does, where it returns?
Posted on 2004-04-15 18:24:03 by f0dder
This code seems to return the correct values. They are still different though.
Posted on 2004-04-18 15:51:48 by QvasiModo
oh Qvasi, I forgot to use pass an addr for the threadid parameter, 9x requires this. Silly me ^_^
Posted on 2004-04-18 16:02:38 by f0dder
I guess so :P Well I like to always make my code short rather than fast, especially when it's only going to be run once and only take less than a microsecond anyway. Oh wait... was there ever a 9X version with kernel32 mapped at anything other than BFF70000? Maybe it was all unnecessary after all :P

Btw, I had a slight typo, the was supposed to be of course
Posted on 2004-04-18 16:59:20 by Sephiroth3
"... was there ever a 9X version with kernel32 mapped at anything other than BFF70000?"

Yep, winME had Kernel32 loaded @ BFF60000 (IIRC)
Posted on 2004-04-21 03:05:23 by Czerno