Hi I'm trying to make a Import table builder in python script just like MacT's Import Reconstructor.
But I have a trouble to find out the method to get an original API information from the forwarded API.
For instance, I got a "ntdll!RtlDecodePointer" from IAT but It's forwarded from the "kernel32!DecodePointer" and I have no ideas to find it out.
Should I have to search through every single loaded modules' ForwarderChain in Import directory?
no,
ForwarderChain in Import directoryunrelated to this.when loader resolve
kernel32.DecodePointerfrom some PE import - it view that it point to some address insideIMAGE_EXPORT_DIRECTORYof kernel32.dll - this is so called forwarded export. loader in this case understand thatkernel32.DecodePointerpoint not to code, but to string in formsomedll.somefunctionor in formsomedll.#someordinalas result loader is try loadsomedlland search forsomefunctionby name or forsomeordinalby ordinal. this search how you can view can (and in case forward exports was) recursive. it stopped when we finally got function address not insideIMAGE_EXPORT_DIRECTORY- this address and will be stored in IAT or process fail - we not found dll/or export in this dll.note that deliminator here (between dll and function name - not
!but.) interesting question - what be ifsomedllcontaining.in own name - saymy.x64.dll. old version of windows incorrect process names like this (my.x64.dll.somefunc) because it search first.in string bystrchr- so will be searchx64.dll.somefuncinmydll and fail. but now this is fixed - loader usestrrchr- he search for last.in string.as result yearly we can not specify full dll name with extension -
fail say on xp. but now - win10 exactly, may be win8.1 (need check) this is correct and will be work - xp will be search for
dll.DecodePointerinkernel32while win10 search forDecodePointerinkernel32.dll. also from here pointed that early we can not forward export to module without.dllextension, now - no such limitation. (loader by default append.DLLsuffix to to loaded library name, if it not containing.- so when callLoadLibrary("my")- actually will be opened and loaded"my.DLL", but for"my."or"my.x64"suffix.DLLwill be not appended (.char in name))so if return to your concrete example -
kernel32.DecodePointerpoint to something insideIMAGE_EXPORT_DIRECTORYof kernel32.dll . loader read string by this address -NTDLL.RtlDecodePointer- callstrrchr(orstrchrold versions) on this string for find.and finally loadNTDLL->NTDLL.DLL(suffix added because no.in name) and search forRtlDecodePointer- address found and it not insideIMAGE_EXPORT_DIRECTORYof ntdll.dll - so this is code address. here process stopped and address ofRtlDecodePointerstored in initial PE IAT .you from own side need repeat loader steps. but here exist one problem in modern os - many strings is begin with
API-MS-*dlls names. this is not real dll but The API Set Schema - undocumented and mutable way, how loader resolve this names