Log in

View Full Version : Messin' with the Import table


Kayaker
June 20th, 2001, 23:36
'Lo All,

How about a little challenge this time to manually rebuild an Import table? There's an interesting reversing task as well once the first step is done.

Again I offer up a unique reversing tool as a target, called KeyCode, which is "An auxiliary utility for developers. It gets information generated by Windows under pressed/depressed keys. Such information may be messages sent by Windows, virtual key code, OEM scan code, etc. The utility hides its own window after switching on another application, besides the program activation may be carried out by pressing the hotkey (Ctrl-F12) from any application. The program is freeware and freely distributable". (7K attached file)

PART 1:

What I did was first to dump the program from memory so the Virtual and Raw Offsets would be equal. This makes rebuilding so much easier while working in a hex editor, which is where you're going to be spending most of your time btw, heheh. There and in PEditor.

This was the end of me being Mr. Nice Guy though. I then made 3 distinct types of changes to the Import table. Your job is obvious. The problems aren't extremely difficult, but I think that by the end of it anyone unfamiliar with exactly how the Import section is constructed will have a much better handle on it. I tried to leave enough clues as to the structure of the section that even if you're confused by the documentation, it can still be figured out strictly as a logic exercise. (sort of like a Myst puzzle

A few recommended refs:

Iczelion's PE Format Tutorials (Tutorial 6: Import Table)
http://win32asm.cjb.net/

[yAtEs] Understanding Import Tables
http://www.woodmann.com/yates/Import_tables.txt

TiTi - PE Files Import Table Rebuilding
http://www.woodmann.com/yates/rebuild.txt

PART 2:

The app has the annoying habit of hiding itself as soon as it loses mouse focus. You call it up again with Ctrl-F12. This is by design, so be careful when you're testing during the 1st part, you may have been successful but miss seeing the small window.

The second challenge is to stop the window from hiding itself. Quite do-able in several ways.


Lemme know if there's any questions.

Cheers and Good Luck,
Kayaker

EDIT: Project file reuploaded, this time along with the original KeyInfo program files, Links updated. Dec '03

ThrawN
June 20th, 2001, 23:55
interesting timezone you must be in to write a post at this time. U from down south in australia or something?

CoDe_InSiDe
June 21st, 2001, 00:28
Hi Kayaker,

Hmm.. you made a little mistake in the Import Table ;D
Because the "Base Address" doesn't exists in my System
It was in your "Memory" but not here, now i can never retrieve the correct API, but i'll find it in some way ;D

Cya...

CoDe_InSiDe

CoDe_InSiDe
June 21st, 2001, 00:37
Btw nice "holes" ;D

Cya...

CoDe_InSiDe

CoDe_InSiDe
June 21st, 2001, 00:52
Hi Kayaker,

I think i found the correct API now ;D
The prog runs, on to part 2

Cya...

CoDe_InSiDe

CoDe_InSiDe
June 21st, 2001, 00:57
Hi Kayaker,

Ok, part 2 doine ;D
Err... am i too fast?

(Show The Fricking Window) Hint

Cya...

CoDe_InSiDe

Kayaker
June 21st, 2001, 01:04
Heh heh, you're just too damned fast CoDe_InSiDe. I was just going to up my Win98 copy of the dll in question, when you found the 'lost' API.

Duh, I never even thought of that. I gotta start working on more platforms to be aware of this Do you think I should still up the dll or do you think others could find it as you did, and this could just be part of the challenge for some?

LOL ThrawN. No, I'm in a far Northern time zone, eh? I just keep strange hours, as proven by this even later post ^_^

Kayaker

Kayaker
June 21st, 2001, 01:12
Quote:
CoDe_InSiDe (06-20-2001 22:57):
Hi Kayaker,

Ok, part 2 doine ;D
Err... am i too fast?

(Show The Fricking Window) Hint

Cya...

CoDe_InSiDe


OK, that's it. Next time you get a special CoDe_InSiDe-only, mega-crippled, self-destruct version of the challenge. Sheesh, I can't even keep ahead of your posts! ;D

Regards

CoDe_InSiDe
June 21st, 2001, 01:35
Hi Kayaker,

haha LOL ;D
A Mega-Crippled, Self-Destruct Version sounds good

But anyway, well you can leave it as an Challenge option, for "The Lost API"
I found it by first checking what was pushed for the API, and then thinking a bit and running down Win32.hlp, and tried some ofcourse

So to anyone that has problems finding "The Lost API", try to look for what it pushes and then think a bit about what it is related to?

Then if someone still has problems you can put the DLL

And about Part 2, the solution is quite obvious
The program "Hides" itself, so what do you need to "Unhide" it?

Cya...

CoDe_InSiDe

seir
June 21st, 2001, 07:43
Hi all,

again nice challenge Kayaker and again an other tool to play with.
As part2 of the challenge says you have to stop the window from
hiding itself. Yep, that is an easy task. So for the reverser out
there a little extra challenge:

- Make the window to stay always on top.

It is in fact pretty easy to achieve, you only need one function
(which you have to add to the imports first).
I won't post the solution yet, but if someone has troubles I will
give some hints

- seir

qferret
June 22nd, 2001, 20:10
Call me a glutton for punishment...but I'll try it ;-)

Kayaker
June 22nd, 2001, 22:09
Hi All,

Just want to make sure that anyone spinning their wheels on this one isn't left at the starting gate. I'm wondering if this is the type of project people want to see. Too hard? Too easy? Too boring? Not pertinent?

In response to the last one, I'd say becoming familiar with manually modifying the Import table is *very* pertinent to our sport. Many packers alter the IT, and even Revirgin won't do it all automatically or is even able to handle certain packers. As for Seir's excellent suggestion on adding an Import so you can call that API to handle some function, this is where it becomes pure reversing fun.

The 2 refs I gave should cover it all, but it's probably all pretty confusing on 1st (and 2nd, and 3rd...) reading. I'm not an Import guru by any means, but I'll try to cover what might be important in all that crapola just so those unclear on the concept have some framework to work with. (Hope I don't screw up

I guess the first thing is wheredahell is the Import table? If the name hasn't been changed purposely, then it's usually at the raw offset of the default named .idata section. If this section has been renamed, there's always an RVA (relative virtual address, i.e. "in memory" pointer to it at byte 80h of the PE header. So look for the word 'PE' in a hex editor near the start of the file and add 80 bytes. Subtract from this dword pointer address any difference between the Relative and Raw offsets of the section and you've found it.

I'm not going to repeat the excellent descriptions in the refs I gave, just give a hint as to where to start. I think of the Import table proper as having 4 sections, the IMAGE_IMPORT_DESCRIPTOR (IID), the OriginalFirstThunk, the FirstThunk, and the ASCII names (IMAGE_IMPORT_BY_NAME) section.

The 1st section you'll see is the IID, which consists of a set of 5 dwords giving info about 1 dll. There's one IID for each dll, one after another, and the section is terminated with a set of 5 empty dwords, i.e. all '0000 0000'. This is where you should start examining the changes I made to the file.

The 1st dword in each IID is a pointer to the OriginalFirstThunk. The OriginalFirstThunk doesn't always exist, so sometimes you'll see this dword empty. If it does, the dword will be an RVA pointer to the start of an array, or table, that contains *other* RVA pointers to the ASCII name of each API in the dll. Each OriginalFirstThunk array is terminated by a single empty dword, so this is how you can recognize the *next* OFT section for the next dll.

The 5th dword in each IID is a pointer to the FirstThunk, which is essentially a duplicate of the OriginalFirstThunk. The difference between the two can be seen if you dump the file from memory, or look at the Import table while in SoftIce. The FirstThunk now contains the actual memory addresses of each API, instead of just RVA pointers to the ASCII name. This is done when the PE file loads in memory, the FirstThunk is initialized. Actually, if you look at your copy of notepad, you may see that the FirstThunk already contains the real addresses for each API.

The 4th dword of the IID is just a pointer to the name of the dll.

I think this should be enough info to start trying to rebuild the Import table I f***** up. Hope this helps.

BTW, I thought of another possibility to extend this project, after trying Seir's task of course. It strikes me we have the beginnings of a keyboard logger here. The program is already processing keystrokes, you'd just need to dump the characters to a buffer perhaps, and write the buffer to a file after so many keystrokes. Any takers? ;D

Kayaker

qferret
June 22nd, 2001, 23:25
I volunteer CoDe_InSiDe for the keylogger LOL

CoDe_InSiDe
June 23rd, 2001, 00:32
Hehe qferret
Maybe i'll take a look at it, dunno yet
I'm currently busy with Unpacking stuff ;D

Cya...

CoDe_InSiDe

P.S. does any of you guys outthere, have the Encrypter "NoodleCrypt v1" or know any URL to it???
I'm searching desperately for it ;D
TIA

Clandestiny
June 23rd, 2001, 13:55
Hi All,

Well, I think I've got it pretty much fixed, except for that darn missing API... As soon as I find it I'll post some of my results. Anyway, just wanted to poke my head in and say I'm working on it

And also, for anyone who's as new to this as I am, I found an EXCELLENT tut on rebuilding the import table. After I read it through a couple of times things started to make so much more sense. I'm gonna u/l it to this message as an attachment in case any of you need another good reference.

Regards,
Clandestiny

seir
June 23rd, 2001, 14:31
Hi Kayaker, Clandestiny,

cool idea turning the tool into a keylogger. But I think it is pretty
difficult to do. The problem is that it only shows the keycodes
if the keycode window is active (has the focus). The WM_KEY*, WM_SYSKEY*
messages are only sent to the window, which has the keyboard focus.
This means to turn it into a keyboard logger, we would have to make
a dll/vxd which hooks the keyboard and forwards the messages to our keycode
program.
It is possible, but that would be more a programming challenge than a reversing
challenge. I don't think there is another solution, but who knows ...

Clandestiny: Finding the missing API is the more difficult part of the challenge
(if you are already familiar with the import table ) Hint: Look as Code_Inside
already said at the parameters pushed to the API and also look at the API
following our missing one *big hint*.

- seir

Clandestiny
June 23rd, 2001, 14:40
Yipee!!! The first time I've ever rebuilt an import table and it actually works ;D . As it ends up, that missing API was not so hard to find...we have the same memory address for that API, Kayaker ...And I can tell either you (or I) have been playing Myst far too long... hehe, it really was like a Myst puzzle... all the missing pieces in the right places

Regards,
Clandestiny

Kayaker
June 23rd, 2001, 17:44
Good point seir, by the time you install the hook procedure you'd have most of the keyboard logger written anyway. And then to have to pass that to the existing program just to process the keystroke, and then write more code to dump to a file is just plain dumb. Guess I didn't think that one through. I suppose you *could* reverse it to generate a log file just so you've got an output of scan and key codes for your keyboard, but I guess that's not really all that useful

Heh, I guess those Squee Chirps from Myst3 finally got to me Clandestiny ;p I had totally forgotten about that ImportReb essay, which I know I've got *somewhere*. It's a good one.

OK, that was a gentle introduction to Import rebuilding. I have a feeling it may come up again

Cheers,
Kayaker

Rage9
June 23rd, 2001, 18:38
Wow, this is the first time I have ever tryed this, well there's a first time for everything but im having a little bit of trouble.... i was wondering if im going in the right direction, would you have to add an IMAGE_IMPORT_DESCRIPTOR structure for the USER32.DLL??? Right inbetween the other 2 dll's? just wondering if i was on the right track, l8er...

-Brad

Kayaker
June 23rd, 2001, 19:11
Hi Rage9,

Yup, you got it

regards

qferret
June 23rd, 2001, 23:31
I'm almost there guys...& I haven't even had to bug JimmyClif (mainly cuz he hasn't looked at it yet LOL)

Hey CoDe_InSiDe,

noodlespa.cjb.net->My Fantastic Programs ;-)

qferret
June 24th, 2001, 00:09
Well, since it looks like most participating in this are done, or close to it, I'll share what I have so far....

I have 2 of the 3 IT probs fixed (I think).
But I'm having a tough time figuring out what the 3rd is, much less fix it.

The missing IID & API were easy to spot, although I did have to do some reading and studying of the rest of the IT to figure out how to fix it ;-)

Anyway...

I added the IID for User32.DLL, double & triple, etc. etc. checked the addresses that the OFT and FT pointed to (btw, are they right b4 and right after the ASCII names in all proggies?)

Then I hit cntrl d and typed "d cs:The_Address_Of_The_Missing_API"...whattaya know? now I know the missing API name. I then replaced the address in the FT array with the offset for that spot from the OFT array, and put the name in the ASCII name list.

Anyone want to gimme a clue as to what the 3rd prob is?

CoDe_InSiDe
June 24th, 2001, 02:31
Hi qferret,

"Hey CoDe_InSiDe,

noodlespa.cjb.net->My Fantastic Programs ;-) "

Nope, that's only NoodleCrypt v2
v1 is nowhere to find ;D

Cya...

CoDe_InSiDe

P.S. Kayaker throw in another Import Table challenge, it's easy :P

qferret
June 24th, 2001, 09:16
aw nuts....well I tried for ya CoDe_InSiDe *G*

Clandestiny
June 24th, 2001, 15:09
Hiya ?ferret,

Sounds like you fixed up everything for the User32 imports, but there are other problems w/ both the Kernel32 and User32 portions of the table... They're just not as obvious

Hint for Kernel32: The Image Import Descriptor may look ok... but take a closer look at the unbound IAT array section. Could there be a few missing pieces ?

Hint for Gdi32: Recheck the First Thunk pointer to IAT and the IAT entry itself.

Regards,
Clandestiny

qferret
June 24th, 2001, 15:42
I did fill in the missing offsets for Kernel32....but I didn't catch anything wrong in the IID for GDI32.....will check it out, thanks :-)

Muad'Dib
June 24th, 2001, 16:10
I finally finished this project. I worked on it for a few hours over a span of 2 or 3 days and, though it was difficult (I knew nothing of the IT and hardly anything about PE before I started) I can now say that I learned quite a bit about how the IT works. Thanks, Kayaker, for the great project, now on to part 2...

Muad'Dib
June 24th, 2001, 16:29
Quote:
qferret (06-24-2001 13:42):
I did fill in the missing offsets for Kernel32....but I didn't catch anything wrong in the IID for GDI32.....will check it out, thanks :-)


I don't think that there is anything wrong with the IID for GDI32...everything works fine and I didn't have to alter that one at all.

Rage9
June 24th, 2001, 17:26
I must admit that finding the missing api has bit me like some kinda screwy bug! CoDe_InSiDe did you find it without softice? Any hints? If it gives it away send me an e-mail...

And one more quick question, can you still run the program without the missing api? Or do you absolutly need to find it?

-Brad

Kayaker
June 24th, 2001, 17:54
Hi All,

Hey that's great Muad'Dib, that's *exactly* what I was hoping for! IT corruption is such an important part of some protections, and it's just an interesting place to play around with anyway, that I thought it might make a fun project.

Packers and such tend to use more of a redirection of the pointers in the Thunk array, rather than the deliberate mangling I did, but it's good to understand the section so you know what's supposed to point to what under normal conditions. Instead of being initialized directly with the addresses of the Imports they may call some routine which gets you there indirectly, such as a jump to the API after some SMC, or maybe decrypting a previously encrypted Import name, then calling GetProcAddress to get its address.

As well, I know there's some utilities around like IIDKing by SantMat which allow you to add Imports, but I like to have the knowledge how to do this manually just for a lark.

BTW ?ferret, I think Clandestiny is trying to throw you off track with that GDI32 stuff. At least I don't remember mucking with gdi

Rage9, if you're running Win98 you could use Exescope on the system dll in question to find the address. If not, then it would be a different address than mine (mea culpa on that one), in which case educated guesswork is in order I suppose. And if you've fixed everything *else* up, I *hope* it doesn't run without that missing API, it's not supposed to

Regards all,
Kayaker

?ferret
June 24th, 2001, 18:34
Hi all,

Well, after chattin with Clandestiny and figuring out what I missed, it ran on his system....but not mine.

I started over with a fresh copy, redid all (i hope) the changes, & it still won't run.

I'm attaching my copy of the proggy. Could someone test it to see if it's just a problem w/ running it on my box? I'm gonna look again to see if I missed anything, but I think I got it all ;-)

Thanks,

?ferret

?ferret
June 24th, 2001, 18:36
uh Kayaker? .....if the proggy works.....feel free to delete it LOL.....oops

Clandestiny
June 24th, 2001, 19:42
Hiya Kayaker, ?ferret

Quote:
Kayaker (06-24-2001 15:54):
BTW ?ferret, I think Clandestiny is trying to throw you off track with that GDI32 stuff. At least I don't remember mucking with gdi


Nah Kayaker, I wouldn't be mean like that ;-) Here's what I really meant to say... There's no problem with the Image Import Descriptor Struct for the GDI32 dll.

0x00001000 50 10 00 00 72 C2 3E 35 00 00 F2 BF C4 13 00 00 P...r.>5........
0x00001010 E8 13 00 00

...But there is a problem w/ the IAT for the Gdi32 dll. At the RVA to IAT (offset 13E8h) the pointer points to the memory address rather than the ascii string name.

0x000013E0 32 2E 44 4C 4C 00 00 00 13 49 F2 BF 00 00 00 00 2.DLL....I......

Where you've got BFF24913h you should have offset 10F8 which points to our GDI API name GetStockObject. Thats what I meant when I hinted to ?ferret to have another look at the GDI stuff. Sorry about the confusion.

To ?ferret: I ran that copy of your .exe again that we fixed earlier just to make sure I wasn't having delusions / ran the wrong file / did something really stupid...ect... ;-) And it still works. But I d/l the file you just u/l to the board and it crashes. I don't think I changed anything other than those 2 little things we talked about...so you got me puzzled. I'll have a look at the u/l file and see if I see any problems.

Regards,
Clandestiny

qferret
June 24th, 2001, 20:18
It works It works!!! LOL

Thanks Clandestiny (can't believe I 4got to reverse the byte order on that offset) ^_^

And thanks to Kayaker for these projects.....learning ALOT of new and interesting (not to mention useful) stuff.

qferret
June 24th, 2001, 21:25
part 2 was the easy part....just changed a ShowWindow param ;-)

CoDe_InSiDe
June 25th, 2001, 00:26
Hi Rage9,

"CoDe_InSiDe did you find it without softice? Any hints?"

Yes i did it without SoftICE
Like i said before in some post, try to search for what it pushes before the call to the API (Try to make a Dead Listing, that'll help )

Cya...

CoDe_InSiDe

Efbe!Mjtujoh!.?!Tuso!Sfg!.?!XN`DIBS

Eternal Bliss
June 25th, 2001, 08:11
Hiya,
I rebuilt the IT, but somehow, it ran a bit then crash with a kernel32 thingy. Tracing into the proggy, I realise that the crash is always at postmessage or getmessage (can't remember which one). Can someone check my IT for me? 8P

Regards
EB

Kayaker
June 25th, 2001, 11:18
Hi Eternal Bliss,

I see what's happening. The original 'missing' Import had an initialized address in the First Thunk of 1D17 F5BF, but its API name was missing.

You replaced the First Thunk pointer correctly to where the name should be, but didn't get the API name right. Instead you got the name corresponding to the address BFF51118 instead of BFF5171D. From what you did replace the name with I'm thinking you're running Win98 as well, but just in case I'll up my version of User32.dll (28K zip) so non-98 users can find the address easier.

Cheers,
Kayaker

Rage9
June 25th, 2001, 12:27
weeeee!! i solved it! haha! turns out i did it all right, even found the right api! but I hade one byte offset switched around on accident.... onto part two...

-Brad

Rage9
June 25th, 2001, 12:37
damn part 2 was easy....

-Brad

CoDe_InSiDe
June 25th, 2001, 12:45
Hi Rage9,

Way to go !!! ;D

Cya...

CoDe_InSiDe

NeO'X'QuiCk
June 25th, 2001, 16:29
Kayaker the project is good i like it like i liked the one before this!But i didnt manage to solve it yet !!but ...


NeO'X'QuiCk

qferret
June 26th, 2001, 22:48
Hola,

Me again ;-)

I'm trying to add the import SetWindowPos to try to add code to keep it on top.

I added the ASCII name, added the offset to the IAT; fixed all the IAT offsets, IID offsets, etc. in my hexeditor; adjusted the image size and the IT sizewith PEEditor, and it crashes....no error messages, just the hourglass for a second & then nothing. It doesn't hang in mem, because I can edit it again w/o rebooting hehe (1 good sign).

What else do I have to update/change to add imports?

I even tried IID King to see how it did its work, but it says there's not enough room, so that didn't work to show me either :-(

The good news is, I did manage the first 2 tasks & I'm still playin around with it LOL.

Kayaker
June 26th, 2001, 23:48
Hi ?ferret,

That error message with IIDKing is sort of a bug between it and PEditor. PEditor inserts its 'advertising' right at the end of the section table in the PE header. Along comes IIDKing and it's looking for a bunch of 00's as a delimiter for the section table so it can add a new section to place your sneaky new imports and a new IID, but doesn't find it.

Just replace the "Modified with PEditor..." text with 00's and IIDKing should work.

I know, I know, I should buy the new LordPE util. Hey Hz, can I bum $13 from ya? Maybe we can get a group rate?

btw, I checked out the LordPE demo the other night and, well yeah, it's a crippled demo all right

Kayaker

Lord_SplAj
June 27th, 2001, 07:53
LOL........LordPE /notrademark .............ooohh I my paid for version also adds imports easier than IIDK


money well spent, thanks y0da :-)

anon_splaj

qferret
June 27th, 2001, 23:11
Thanks for the tip Kayaker, it worked beautifully. But is there a tool that will add an import w/o adding a section? or is this not possible/too hard?

I just had a brief look at it so far, but I think I should be able to figure out how it was done. I would just rather have it look "original" ;-)

Eternal Bliss
June 28th, 2001, 06:02
Quote:
Kayaker (06-25-2001 09:18):
Hi Eternal Bliss,

I see what's happening. The original 'missing' Import had an initialized address in the First Thunk of 1D17 F5BF, but its API name was missing.

You replaced the First Thunk pointer correctly to where the name should be, but didn't get the API name right. Instead you got the name corresponding to the address BFF51118 instead of BFF5171D. From what you did replace the name with I'm thinking you're running Win98 as well, but just in case I'll up my version of User32.dll (28K zip) so non-98 users can find the address easier.

Cheers,
Kayaker


Thanks. 8) Did it. 8)

the second part:
1) I used resource editor to make the form always on top.
2) I look for showwindow and see which one has a PUSH 00000000 which is SW_HIDE and changed it.

Regards.
EB

Kayaker
November 29th, 2001, 20:02
For anyone following the API Hooking thread on the main forum, here's a reupload of the original project program, which is OK to remain here.

Kayaker

Kayaker
December 1st, 2003, 02:59
Hmm, I forgot I had reuploaded this lost project file. I just reupped it again to the original post, this time along with the original KeyInfo program file, so should make it easy to compare a correct import table with the 'corrupted' one for those just getting their feet wet. Links updated as well.
(yes I know I originally called the program KeyCode, but that was a ruse so nobody tried downloading the *real* KeyInfo program to cheat ;-)

Kayaker

nofurs
December 1st, 2003, 11:04
Well maybe someone did who knows (ouch! an accusation again? LOL