Log in

View Full Version : assembling my own prog to 'fix' import data sections


Kr0n0
August 21st, 2002, 17:38
hi...
i'm trying to do my own ImportSectionBuilder, but i'm not sure if i'm taking the right direction or screwing up
the prog takes an input something like this:
-------------------------------------------------------
kernel32.dll: CreateFileA CloseFile ExitProcessA
user32.dll: MessageBoxA
...etc...
-------------------------------------------------------
but does the order of the imports matter? i mean, if in the original importsection kernel32 imports came first, can the user32 come first on the rebuilt importsection
and what about the 'Hint' does it interfere in any way the imports's order? or can i set it as NULL


thanks for your help and any feedback and sugestions are appreciated

ps: if anyone wants to get involved with this or make this as a miniproject RCE (since i'm a newbie myself) just say so



kr0n0 aka k0m0d0

DakienDX
August 21st, 2002, 17:53
Hello Kr0n0 !

I'm not sure if I understand what you're trying to do.

Are you trying to write a program which creates an import table which you can insert in any of your programs and redirect the calls to the imports later or are you trying to re-build an import table for an application you cracked?

If you're just trying to build your own import table to learn and play with, the order of the imports and DLLs doesn't matter, since you will only have a few you can redirect by hand.

However, if you are working with some comercial application where you want to rebuild the import table (because it was messed up by a packer) you must care about both the order of the DLLs and the exact order of the imports.

The "Hint" doesn't matter. You can set it to 0000h without any problems. Several compilers do this by their own.

esther
August 21st, 2002, 17:54
Hi Kr0n0,

It depends on the program itself.trace through the code using softice or you can use Revirgin or Imprec to see how its done.

Regards

[yAtEs]
August 22nd, 2002, 12:30
Quote:
Originally posted by Kr0n0

but does the order of the imports matter? i mean, if in the original importsection kernel32 imports came first, can the user32 come first on the rebuilt importsection
and what about the 'Hint' does it interfere in any way the imports's order? or can i set it as NULL


in theory the order of your dll IAT's doesnt nor do the
descriptors matter as long as its all correctly created (-; oh
and hints can be null too.

but pratically remember to take into consider the IATs order
if your chopping and changing something since code is patched
to the entries

yates.

Kr0n0
August 22nd, 2002, 13:40
i see...

but do the packers/cryptors always screw up the .idata the same way? it seems not. (i've only done 4 packers: and of those 4 only upx and fsg screw it up)

so in your opinion what approach should i take?
1) fix the .idata from scratch, simply using the imported names functions and .DLL
search for imported function
rebuild the corresponding part of the .idata using GetProcAddress and GetModuleHandle
get to next import

2) use the screwed .idata
search for imported function
check to wich .DLL it belongs
rebuild the corresponding part of the .idata using GetProcAddress and GetModuleHandle
fix RVAs in the .idata
get to next import


i think 1) is simpler and it simply relies on the import names and .DLL being present, which are always there!

and about the ordinal thing? if it's imported in ordinal, the only thing i have to worry it so the RVA point to [address_of_imported_function - 2] right?


thanks for your replies

[yAtEs]
August 22nd, 2002, 14:41
Quote:
Originally posted by Kr0n0

but do the packers/cryptors always screw up the .idata the same way? it seems not.

so in your opinion what approach should i take?



nope, depends what your doing, what do you want to achieve?
, sounds like your trying to build a whole new import table
for any upacker which might be tedious (;

if its for a specific packer you better off learning what it does
to the import table and reversing the changes, or dumping from
oep and figuring out a fix method, rather than taking the phrase
rebuild an import table so literally ;-) the 'more raw' approach
which you seem to be taking can be done for a specific packer if
you know how it works and where tables/asciis and stuff are stored.

thats what i think anyway, i probably got it all completely wrong
what ur doing, but hey thats me ;-)

yates.

DakienDX
August 22nd, 2002, 18:24
Hello Kr0n0 !

Not all packers/protectors screw up the import section the same way (you usually don't say "screw" for packers, since they only do what windows would do else). There are generally several ways.

The simple way would be if the packer simply packs the .idata section as it is and unpacks it while executing the .EXE. This way you have an .idata section which you can dump (before the unpacker starts to load the imports) and insert in your dumped program.

An other way, used by UPX also, is that the packer re-aranges the .idata section before it compresses it, so that there is less data which needs to be compressed. This way you'll never have a "normal" working .idata section while unpacking. So you've to rebuild the import table with some import rebuilder.

A third way, usually not used in simple packers, is that the protector re-aranges the .idata section before encrypting it, like before, but also redirects the imported functions to it's own routines. This way you won't be able to rebuild the import section by looking which address belongs to which function in which DLL, since the import table's entries point to the protector's code instead of the imported functions.

Kr0n0
August 22nd, 2002, 19:45
my idea is to make a generic .idata rebuilder, that picks up the imported names and .dll files from an unpacked-and-non-functional .idata that was dumped using icedump, just after the packer/cryptor as unpacked/decrypted it, or just before it reaches EP of prog! (i hope i clears things out

[yAtEs]
but from what you said the closest thing i can get i to make a generic .idata 'fixer' only for a specific packer/cryptor of it's corresponding version

DakienDX
1) like EZIP or EXE32PACK

2) like UPX or FSG

3) this is a hard one the RVAs instead of pointing to a symbol name (ex:MessageBoxA) points to a symbol of the packer (ex:a symbol in a .dll of the packer)
but the symbols that are present in the RAM after it decrypted are used indeed; OR are there for confusing and use the redirection and there the redirection procedure gets the real imports and fixes the FirstThunks of the decrypted .idata in RAM


i hope i didn't confuse things even more





but for a packer/crypter to work it always have to have the imported_functions and .dll_files stored somewhere! (there's no way out of it), and before it gives control to the prog it has to have ALL FirstThunks with correct addresses to the imported_functions

DakienDX
August 22nd, 2002, 22:15
Hello Kr0n0 !

You will not have problems with KERNEL32, USER32 or other system imports, but non-system DLLs will be a problem if you just use a dump instead of the actual running process.
Let us say the program is using four own DLLs. Each of them has a image base of 10000000h. When the first DLL gets loaded, it will probably be loaded at address 10000000h. But if the next DLL is loaded, the address space it wants to load into is already in use by the other DLL. So this DLL uses a different address space. The same goes for the other two DLLs.

So if you've an entry in the import table pointing to, for example, 10004130h, you can't tell in which DLL to look for the imported function, since all of the four DLLs could have been loaded at that address.

However, if you're rebuilding the import table while the program is running, you can check which DLL is loaded at which address and know in which DLL to search for the imported function.
This problem does not happen with system DLLs like KERNEL32 or USER32, since they are always loaded at the same address in memory.

There is also an additional problem when using a dump. The protector could have destroyed the names of the imported DLLs. So any DLL on your system might be the one you're looking for.

The possibility I talked about the third time works a bit different as you think. The protector might not have stored the imported functions and DLLs somewhere in memory. It has no need to give all FirstThunks correct API addresses before passing control to the decrypted application. It could be that all imported functions just point to one single procedure in the protector's code. When an import is called, the protector calculates the imported function from some of it's own internal tables and jumps directly to the API. This way the program will run like normal, but you'll have never any valid addresses to imported functions in your import table.