{"id":7609,"date":"2011-12-01T12:20:48","date_gmt":"2011-12-01T11:20:48","guid":{"rendered":"https:\/\/www.corelan.be\/?p=7609"},"modified":"2011-12-01T12:20:48","modified_gmt":"2011-12-01T11:20:48","slug":"roads-iat","status":"publish","type":"post","link":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/","title":{"rendered":"Many roads to IAT"},"content":{"rendered":"<h3>Introduction<\/h3>\n<p>A few days ago a friend approached me and asked how he could see the import address table under immunity debugger and if this could be done using the command line.<\/p>\n<p>I figured this would be a good time to take a look at what the IAT is, how we can list the IAT and what common reversing hurdles could be with regards to the IAT.<\/p>\n<p>Let\u2019s see first what is IAT and why it\u2019s good to know what is in there.<\/p>\n<p>IAT stands for Import Address Table and according to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Portable_Executable#Import_Table\" target=\"_blank\" rel=\"noopener\">wikipedia<\/a>,<\/p>\n<blockquote><p>\u201cOne section of note is the <em>import address table<\/em> (IAT), which is used as a lookup table when the application is calling a function in a different module. It can be in form of both <a href=\"http:\/\/en.wikipedia.org\/wiki\/Dynamic-link_library#Symbol_resolution_and_binding\">import by ordinal and import by name<\/a>. Because a compiled program cannot know the memory location of the libraries it depends upon, an indirect jump is required whenever an API call is made. As the dynamic linker loads modules and joins them together, it writes actual addresses into the IAT slots, so that they point to the memory locations of the corresponding library functions. Though this adds an extra jump over the cost of an intra-module call resulting in a performance penalty, it provides a key benefit: The number of memory pages that need to be copy-on-write changed by the loader is minimized, saving memory and disk I\/O time. If the compiler knows ahead of time that a call will be inter-module (via a dllimport attribute) it can produce more optimized code that simply results in an indirect call <a href=\"http:\/\/en.wikipedia.org\/wiki\/Opcode\">opcode<\/a>.\u201d<\/p><\/blockquote>\n<p>By knowing what\u2019s inside IAT we can identify functions that are called from other modules in a program, look for possibly unwanted or strange behavior ( cases on virus \/ malware ) make the code under the debugger easier to read and find address location from functions of interest ( <strong><a href=\"https:\/\/www.corelan.be\/index.php\/tag\/virtualalloc\/\" target=\"_blank\" rel=\"noopener\">VirtualAlloc<\/a><\/strong>, <strong>HeapCreate<\/strong>, <strong>SetProcessDEPPolicy, <strong>NtSetInformationProcess, <strong>VirtualProtect, <strong>WriteProcessMemory<\/strong><\/strong><\/strong><\/strong> ). In case you haven't figured it out, you can use those functions to <a href=\"https:\/\/www.corelan.be\/index.php\/2010\/06\/16\/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube\/\" target=\"_blank\" rel=\"noopener\">bypass DEP<\/a>. Having an accurate pointer in the IAT to one of the functions will make it trivial to call the function in a ROP chain.<\/p>\n<p>&nbsp;<\/p>\n<h3>How can we query or list entries in the IAT ?<\/h3>\n<h4>Windbg<\/h4>\n<p>Windbg is many times the debugger of my choice, not because it\u2019s the easiest to use, but mostly I got used to the interface and the fast response. Doing things under windbg in most cases will take far less time, if you know the way and far more time if you are trying to find your way now.<\/p>\n<p>After launching windbg, this is what you'll get:<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg\" alt=\"windbg\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>You can start a debugging process under windbg by launching an application in the debugger (File - Open) or by attaching the debugger to a running application (File - Attach). For the purpose of this example we are going to use notepad.exe as test file,<\/p>\n<p style=\"text-align: left;\"><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg-notepad.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg-notepad.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p style=\"text-align: left;\">windbg will load the modules and it will stop just before the execution of the program waiting for command. All modules loaded at this moment can be viewed in the screen.<\/p>\n<p>As opposed to the other two debuggers, windbg lacks the easy drop down menu commands and identifying IAT requires a bit more time. First we need to locate the address of the Import Address Table in our executable, to do so the command !dh will be used:<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-location2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-location2.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>!dh command will <span style=\"color: #000000;\">D<\/span>isplay the Headers of the requested module, (more for the commands at : <a href=\"http:\/\/windbg.info\/doc\/1-common-cmds.html\">http:\/\/windbg.info\/doc\/1-common-cmds.html<\/a>) where we can identify the location, address of IAT. In my example IAT for notepad is located at memory address 1000 of the module notepad.exe.<\/p>\n<p>Dumping the content of the address we need to add the image base of our file plus the memory address of the IAT table, this can be done easily using two ways, either by using \u201cdps notepad+1000 l1000\/8 \u201c or by giving the image base address, \u201cdps 00c10000+1000 l1000\/8 \u201c. dps command stands for <strong>d<\/strong>isplay <strong>p<\/strong>ointer-<strong>s<\/strong>ized contents of memory in the given range.<\/p>\n<p>The output of the dps command will give us a lengthy result with the contents of the IAT table and the location of the functions.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg-notepad-dps.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg-notepad-dps.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Another method again for windbg and a bit more elegant is described at <a title=\"http:\/\/www.osronline.com\/showthread.cfm?link=155938\" href=\"http:\/\/www.osronline.com\/showthread.cfm?link=155938\">http:\/\/www.osronline.com\/showthread.cfm?link=155938<\/a>, using the following windbg script,<\/p>\n<div>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">1: r $t0 = poi(${$arg1}+poi(${$arg1}+0x3c)+0xd8)\n2: r $t1 = poi(${$arg1}+poi(${$arg1}+0x3c)+0xdc)\n3: dps ${$arg1}+$t0 l? (($t1+4)\/4)<\/pre>\n<\/div>\n<p>saving the script under a name, eg: test1.txt in windbg directory and calling the script from windbg with $$&gt;a&lt; test1.txt notepad, we will have the following output on the debugger:<\/p>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">0:000&gt; $$&gt;a<span style=\"color: #0000ff;\">&lt;<\/span> test1.txt notepad\n00121000  760e14d6 ADVAPI32!RegSetValueExWStub\n00121004  760e46ad ADVAPI32!RegQueryValueExWStub\n00121008  760e469d ADVAPI32!RegCloseKeyStub\n0012100c  760e1514 ADVAPI32!RegCreateKeyW\n00121010  760e468d ADVAPI32!RegOpenKeyExWStub\n00121014  760e448e ADVAPI32!IsTextUnicode\n00121018  760e369c ADVAPI32!CloseServiceHandleStub\n0012101c  760db537 ADVAPI32!QueryServiceConfigWStub\n00121020  760dca4c ADVAPI32!OpenServiceWStub\n00121024  760dca64 ADVAPI32!OpenSCManagerWStub\n00121028  00000000\n0012102c  763d55de kernel32!FindNLSStringStub\n00121030  763ba125 kernel32!GlobalAllocStub\n00121034  763ba183 kernel32!GlobalUnlock\n00121038  763ba235 kernel32!GlobalLock\n0012103c  763bafc0 kernel32!GetTimeFormatW\n00121040  763bb1a2 kernel32!GetDateFormatW\n00121044  763baaef kernel32!GetLocalTimeStub\n00121048  763b2b7b kernel32!GetUserDefaultUILanguageStub\n0012104c  763bc3c0 kernel32!HeapFree\n00121050  77a82dd6 ntdll!RtlAllocateHeap\n00121054  763bfcdd kernel32!GetProcessHeapStub\n00121058  763bbdad kernel32!GetFileInformationByHandleStub\n0012105c  763bc452 kernel32!InterlockedExchangeStub\n00121060  763b0368 kernel32!FreeLibraryAndExitThreadStub\n00121064  763c4c14 kernel32!GetFileAttributesWStub\n00121068  763ffd71 kernel32!Wow64RevertWow64FsRedirectionStub\n... <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">snip<\/span><span style=\"color: #0000ff;\">&gt;<\/span> ...\n001213e0  77a64168 ntdll!RtlInitUnicodeString\n001213e4  77a760f8 ntdll!NtQueryLicenseValue\n001213e8  77a504a5 ntdll!WinSqmAddToStream\n001213ec  00000000\n001213f0  74f91a15 VERSION!GetFileVersionInfoExW\n001213f4  74f918e9 VERSION!GetFileVersionInfoSizeExW\n001213f8  74f91b51 VERSION!VerQueryValueW\n001213fc  00000000\n00121400  90909090<\/pre>\n<p>&nbsp;<\/p>\n<p>Common commands for windbg, http:\/\/blogs.msdn.com\/b\/willy-peter_schaub\/archive\/2009\/11\/27\/common-windbg-commands-reference.aspx<\/p>\n<p>&nbsp;<\/p>\n<h4>OllyDBG<\/h4>\n<p>Much simpler than windbg, ollydbg will easily display the IAT using the following steps :<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ollydbg1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ollydbg1.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Load the executable of your choice, then from the View menu option we select \u201cexecutable modules\u201d. Next, from the window with the modules, right click on the module that you want to query, and select \u201cView Names\u201d<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ollydbg-module-iat1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ollydbg-module-iat1.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>This will produce the following output:<\/p>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">Names in notepad\nAddress    Section    Type    (  Name                                    Comment\n00C113D4   .text      Import     OLEAUT32.#2\n00C113C8   .text      Import     COMCTL32.#345\n00C113D0   .text      Import     OLEAUT32.#6\n00C11178   .text      Import  (  GDI32.AbortDoc\n00C11310   .text      Import     msvcrt._acmdln\n00C11308   .text      Import     msvcrt._amsg_exit\n00C11324   .text      Import  (  msvcrt._cexit\n00C11238   .text      Import  (  USER32.CharNextW\n00C111CC   .text      Import  (  USER32.CharUpperW\n00C1123C   .text      Import  (  USER32.CheckMenuItem\n00C11274   .text      Import  (  USER32.ChildWindowFromPoint\n00C11348   .text      Import  (  COMDLG32.ChooseFontW\n00C11240   .text      Import  (  USER32.CloseClipboard\n00C1112C   .text      Import  (  KERNEL32.CloseHandle\n00C11388   .text      Import     WINSPOOL.ClosePrinter\n00C11018   .text      Import     ADVAPI32.CloseServiceHandle\n00C113A0   .text      Import     ole32.CoCreateInstance\n00C113A8   .text      Import     ole32.CoInitialize\n00C11394   .text      Import     ole32.CoInitializeEx\n00C11350   .text      Import  (  COMDLG32.CommDlgExtendedError\n... <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">snip<\/span><span style=\"color: #0000ff;\">&gt;<\/span> ...\n00C112F4   .text      Import  (  msvcrt.wcsrchr\n00C110A8   .text      Import  (  KERNEL32.WideCharToMultiByte\n00C1126C   .text      Import  (  USER32.WinHelpW\n00C113E8   .text      Import     ntdll.WinSqmAddToStream\n00C113DC   .text      Import     ntdll.WinSqmIncrementDWORD\n00C1106C   .text      Import     KERNEL32.Wow64DisableWow64FsRedirectio\n00C11068   .text      Import     KERNEL32.Wow64RevertWow64FsRedirection\n00C110B0   .text      Import  (  KERNEL32.WriteFile\n00C112E4   .text      Import  (  msvcrt._wtol\n00C1131C   .text      Import     msvcrt._XcptFilter<\/pre>\n<p>&nbsp;<\/p>\n<h4>Immunity Debugger<\/h4>\n<p>Immunity debugger is based on Ollydbg so the same process for displaying the IAT of a module under Ollydbg applies to it as well.<\/p>\n<p>Since Immunity debugger has support for python scripting, we can use the great mona.py python script from Corelan Team (download here: <a href=\"https:\/\/github.com\/corelan\/mona\">http:\/\/redmine.corelan.be\/projects\/mona<\/a> manual can be found here : <a href=\"https:\/\/www.corelan.be\/index.php\/2011\/07\/14\/mona-py-the-manual\/\">https:\/\/www.corelan.be\/index.php\/2011\/07\/14\/mona-py-the-manual\/<\/a> ).<\/p>\n<p>Let\u2019s see what options we have.<\/p>\n<p>First of all mona.py includes in the latest version a new function called \u201cgetiat\u201d making the process of enumerating the IAT table of all loaded modules a very easy process.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/immunity-with-mona1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/immunity-with-mona1.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Running mona.py with getiat function will give us the following results:<\/p>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">Log data\nAddress    Message\n75F91340   At 0x75f91340 in rpcrt4.dll (base + 0x00001340) : 0x763bd7b5 (ptr to api-ms-win-core-processthreads-l1-1-0.getcurrentprocessid)\n75F910E8   At 0x75f910e8 in rpcrt4.dll (base + 0x000010e8) : 0x77a752c8 (ptr to ntdll.ntallocateuuids)\n75F9117C   At 0x75f9117c in rpcrt4.dll (base + 0x0000117c) : 0x77a75348 (ptr to ntdll.ntalpccreatesectionview)\n75F910EC   At 0x75f910ec in rpcrt4.dll (base + 0x000010ec) : 0x77a76218 (ptr to ntdll.ntquerysystemtime)\n75F91144   At 0x75f91144 in rpcrt4.dll (base + 0x00001144) : 0x77a52fc6 (ptr to ntdll.tpallocalpccompletionex)\n75F910F0   At 0x75f910f0 in rpcrt4.dll (base + 0x000010f0) : 0x77a6206f (ptr to ntdll.etweventenabled)\n75F91228   At 0x75f91228 in rpcrt4.dll (base + 0x00001228) : 0x763a8d68 (ptr to api-ms-win-core-handle-l1-1-0.sethandleinformation)\n75F910F4   At 0x75f910f4 in rpcrt4.dll (base + 0x000010f4) : 0x77aa9d5b (ptr to ntdll.etweventwritetransfer)\n75F910F8   At 0x75f910f8 in rpcrt4.dll (base + 0x000010f8) : 0x77a427d7 (ptr to ntdll.etweventactivityidcontrol)\n75F912D4   At 0x75f912d4 in rpcrt4.dll (base + 0x000012d4) : 0x75dc7ac4 (ptr to api-ms-win-core-memory-l1-1-0.virtualfree)\n75F9118C   At 0x75f9118c in rpcrt4.dll (base + 0x0000118c) : 0x77a76708 (ptr to ntdll.ntsetiocompletionex)\n75F910FC   At 0x75f910fc in rpcrt4.dll (base + 0x000010fc) : 0x77a75338 (ptr to ntdll.ntalpccreateresourcereserve)\n75F91414   At 0x75f91414 in rpcrt4.dll (base + 0x00001414) : 0x75dc99af (ptr to api-ms-win-security-base-l1-1-0.equalsid)\n75F91300   At 0x75f91300 in rpcrt4.dll (base + 0x00001300) : 0x75de3c94 (ptr to api-ms-win-core-namedpipe-l1-1-0.getnamedpipeclientcomputernamew)\n... <span style=\"color: #0000ff;\">&lt;<\/span><span style=\"color: #800000;\">snip<\/span><span style=\"color: #0000ff;\">&gt;<\/span> ...\n747111EC   At 0x747111ec in comctl32.dll (base + 0x000011ec) : 0x765a72c0 (ptr to gdi32.bitblt)\n747111F0   At 0x747111f0 in comctl32.dll (base + 0x000011f0) : 0x765a5ddf (ptr to gdi32.getstockobject)\n747111F4   At 0x747111f4 in comctl32.dll (base + 0x000011f4) : 0x765af4e3 (ptr to gdi32.createpen)\n747111F8   At 0x747111f8 in comctl32.dll (base + 0x000011f8) : 0x765afc35 (ptr to gdi32.getcharwi<\/pre>\n<p>Making things even easier, mona.py has the ability to search for a specific function using the \u201c-s\" parameter, so the command \u201c!mona getiat \u2013s *virtualalloc*\u201d will give us these result:<\/p>\n<p>&nbsp;<\/p>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">           ---------- Mona command started on 2011-10-19 11:54:18 ----------\n0BADF00D   [+] Processing arguments and criteria\n0BADF00D       - Pointer access level : X\n0BADF00D   [+] Generating module info table, hang on...\n0BADF00D       - Processing modules\n0BADF00D       - Done. Let's rock 'n roll.\n0BADF00D   [+] Querying 22 modules\n0BADF00D   [+] Preparing log file 'iatsearch.txt'\n0BADF00D       - (Re)setting logfile c:\\logs\\notepad\\iatsearch.txt\n76371818   At 0x76371818 in kernel32.dll (base + 0x00001818) : 0x75df3691 (ptr to kernelbase.virtualallocexnuma)\n76371914   At 0x76371914 in kernel32.dll (base + 0x00001914) : 0x75dc7a4f (ptr to api-ms-win-core-memory-l1-1-0.virtualalloc)\n76371918   At 0x76371918 in kernel32.dll (base + 0x00001918) : 0x75dc7a08 (ptr to api-ms-win-core-memory-l1-1-0.virtualallocex)\n77BA11BC   At 0x77ba11bc in msvcrt.dll (base + 0x000011bc) : 0x75dc7a4f (ptr to api-ms-win-core-memory-l1-1-0.virtualalloc)\n7695143C   At 0x7695143c in ole32.dll (base + 0x0000143c) : 0x75dc7a4f (ptr to api-ms-win-core-memory-l1-1-0.virtualalloc)\n76AB12F8   At 0x76ab12f8 in shell32.dll (base + 0x000012f8) : 0x75dc7a4f (ptr to api-ms-win-core-memory-l1-1-0.virtualalloc)\n75F912C4   At 0x75f912c4 in rpcrt4.dll (base + 0x000012c4) : 0x75dc7a4f (ptr to api-ms-win-core-memory-l1-1-0.virtualalloc)\n726512C8   At 0x726512c8 in winspool.drv (base + 0x000012c8) : 0x763bc43a (ptr to virtualalloc)\n760D16D0   At 0x760d16d0 in advapi32.dll (base + 0x000016d0) : 0x763ac783 (ptr to kernel32.virtualallocex)\n           [+] This mona.py action took 0:00:00.844000<\/pre>\n<p>&nbsp;<\/p>\n<h4>IDA Pro<\/h4>\n<p>Listing IAT under IDA pro, is much more straight forward than in other debuggers.<\/p>\n<p>After loading our executable in the debugger\/disassembler we can view the import table by either going at menu options,<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IDA-pro-imports.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IDA-pro-imports.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>or directly from the imports tab<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IDA-pro-imports-listing.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IDA-pro-imports-listing.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>You can find more info on IAT at<\/p>\n<ul>\n<li><a href=\"http:\/\/sandsprite.com\/CodeStuff\/Understanding_imports.html\">http:\/\/sandsprite.com\/CodeStuff\/Understanding_imports.html<\/a><\/li>\n<li><a href=\"http:\/\/en.wikipedia.org\/wiki\/Portable_Executable\">http:\/\/en.wikipedia.org\/wiki\/Portable_Executable<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/cc301808.aspx\">http:\/\/msdn.microsoft.com\/en-us\/magazine\/cc301808.aspx<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>What if the IAT looks... weird ?<\/h3>\n<p>During malware analysis, there are many times that a researcher will discover that binary samples are often encrypted or packed, and the IAT is relocated.<\/p>\n<p>This means that the IAT is usually altered, and there are a few ways to do that :<\/p>\n<ul>\n<li>IAT redirection<\/li>\n<li>simple redirection<\/li>\n<li>function entry emulation redirection<\/li>\n<li>API emulation<\/li>\n<\/ul>\n<h4>IAT Redirection<\/h4>\n<p>A normal IAT table should be constructed with the addresses of the functions<\/p>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">Program -&gt; API Functions<\/pre>\n<p>In a situation that IAT table is packed and redirected, IAT is using a proxy address to locate the functions<\/p>\n<p>&nbsp;<\/p>\n<pre style=\"background-color: #252525; width: 650px; overflow: auto; border: #cecece 1px solid; padding: 5px;\">Packet Program -&gt; Proxy -&gt; API Functions<\/pre>\n<p>This method is used in the 'SafeDisc' copy protection mechanism.<\/p>\n<h4><\/h4>\n<h4>Simple Redirection<\/h4>\n<p>Simple redirection is done by overwriting all windows function pointers with pointers back into the protector's code. The protector is using PUSH to put the actual API location on the stack and uses a RET instruction emulating a jump to the correct function.<\/p>\n<h4>Function entry emulation<\/h4>\n<p>In function entry emulation redirection, the IAT table is constructed with references to functions. Those functions often contain some simple instructions with no actual meaning, which are then followed by the actual jump to the real API location. The 'meaningless' instructions are used to complicate the use of automatic unpackers and make it more difficult for people that will try to research and reverse engineer the process.<\/p>\n<h4>API Emulation<\/h4>\n<p>Making things more complicated, API emulation will emulate real API function calls and will return valid (in terms of structure) but wrong information back to unpackers.<\/p>\n<p>A simple example is : it would return the return values of GetTempPath instead of the ones from GetWindowsDirectory.<\/p>\n<p>&nbsp;<\/p>\n<p>More info on the methods can be found here :<\/p>\n<ul>\n<li><a href=\"https:\/\/web.archive.org\/web\/20140802014434\/http:\/\/securitylabs.websense.com:80\/content\/Assets\/HistoryofPackingTechnology.pdf\">http:\/\/securitylabs.websense.com\/content\/Assets\/HistoryofPackingTechnology.pdf<\/a><\/li>\n<li><a href=\"https:\/\/web.archive.org\/web\/20170917224242\/https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms724454(v=vs.85).aspx\">http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms724454(v=vs.85).aspx<\/a><\/li>\n<\/ul>\n<p>Some well known protectors are ASProtect, Themida and Armadillo.<\/p>\n<p>&nbsp;<\/p>\n<h3>Rebuilding IAT<\/h3>\n<h4>ImpREC \/ LordPE<\/h4>\n<p>In order to rebuild the IAT table you will need some tools to make your life easier.<\/p>\n<p>If you plan on using ollydbg\/immunity debugger to do the reverse engineering of the packed binary, you will need the following 2 tools :<\/p>\n<ul>\n<li>ImpREC ( http:\/\/www.woodmann.com\/collaborative\/tools\/index.php\/ImpREC )<\/li>\n<li>LordPE ( http:\/\/www.woodmann.com\/collaborative\/tools\/index.php\/LordPE ).<\/li>\n<\/ul>\n<p>ImpREC is probably the best known IAT re-constructor\/re-builder<\/p>\n<p>LordPE can dump process from the memory, edit PE header sections etc. LordPE was the first tool released for that matter but under Windows 7 you might encounter problems using it.<\/p>\n<p>Alternatively PEtools ( <a href=\"http:\/\/uinc.ru\/files\/neox\/PE_Tools.shtml\">http:\/\/uinc.ru\/files\/neox\/PE_Tools.shtml<\/a> ) , CFF explorer ( <a href=\"http:\/\/www.ntcore.com\/exsuite.php\">http:\/\/www.ntcore.com\/exsuite.php<\/a> ) and PE explorer ( <a href=\"http:\/\/www.heaventools.com\/overview.htm\">http:\/\/www.heaventools.com\/overview.htm<\/a> ) can be used to do the same thing.<\/p>\n<p>&nbsp;<\/p>\n<p>The most common packer for exe files that can be found is undoubtedly UPX (<a href=\"http:\/\/upx.sourceforge.net\/\">http:\/\/upx.sourceforge.net\/<\/a>).<\/p>\n<p>Using the upx executable, we can pack an executable file from the command line :<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/upx-calc.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/upx-calc.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>When you load the non-packed version of calc.exe ( the normal calculator that exists in Windows XP SP3 ) in immunity debugger or ollydbg, you should see the following list of imported functions:<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-Calc.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-Calc.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Loading the UPX packed file, you'll see the list will be significant smaller:<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-packed-Calc.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-packed-Calc.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Packed or not, encrypted or not, the CPU can understand only machine code. That means that, in order for the actual code to run, the executable must get unpacked at some point. To us, it's just a matter of catching that moment. (Danny Quist, Valsmith Covert Debugging)<\/p>\n<p>So, if we want to manually unpack the UPX packed file and re-building the IAT we have to find the actual OEP ( original entry point ) of our code. This is where the \"decoder\/decryptor\/unpacker\" routine is located.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/UPX-code-start.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/UPX-code-start.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Observing the code we will see the use of PUSHAD and POPAD instructions used. This method is used to preserve the state of the registers and execute packer\u2019s code in the following order:<\/p>\n<ul>\n<li>save registers (PUSHAD)<\/li>\n<li>unpack content<\/li>\n<li>restore registers (POPAD)<\/li>\n<\/ul>\n<p>Scrolling down in our code we will find the POPAD instruction and also a JMP instruction in a far location.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/UPX-code-end-and-jump.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/UPX-code-end-and-jump.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Let\u2019s put a breakpoint (F2) on the last jump instruction and run our code until there. This will give us the following results:<\/p>\n<ul>\n<li>The unpacker code will be executed (unpacking the contents of our file in memory)<\/li>\n<li>When the unpacker finishes, we'll hit the breakpoint right before executing the jump to the unpacked code<\/li>\n<\/ul>\n<p>So far so good.<\/p>\n<p>In order to get a copy of the unpacked code in memory, we can simply right click in the ollydbg main window and select \u201cDump debugged process\u201d<\/p>\n<p>Note : If that option is not available, grab a copy of the plugin OllyDump here : <a title=\"http:\/\/www.openrce.org\/downloads\/details\/108\/OllyDump\" href=\"http:\/\/www.openrce.org\/downloads\/details\/108\/OllyDump\">http:\/\/www.openrce.org\/downloads\/details\/108\/OllyDump<\/a>. An alternative way would be to use LordPE or PEtools to dump the process.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/Dump-debugged.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/Dump-debugged.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>From the options that will appear, just remove the option Rebuild Import and select Dump,<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/Dump-file-memory.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/Dump-file-memory.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Leave the debugger running and open ImpREC, under ImpREC select the process that we are debugging and attach to it,<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ImpRec-attach-to-process.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ImpRec-attach-to-process.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>If we try to run the executable at this point, based on what we dumped earlier, we will most likely get an error \u201cthe application failed to initialize properly\u201d. This is normal, because the IAT table is still bad.<\/p>\n<p>In order to identify the IAT structure, Import Reconstructor needs to know the OEP of our application (of the unpacked code)<\/p>\n<p>We noticed earlier in Ollydbg that, right at the end of the unpacker routine, there was a jump for a location outside the packer\u2019s code. This location is the OEP of our application.<\/p>\n<p>If you take that address (the offset from the base address of the module), example \"JMP To Address:01012475 \u2013 Image Base:01000000 = 12475\" , in the OEP section of the ImpRE, and press AutoSearch, our imported functions will be populated.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ImpRec-OEP-Found.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/ImpRec-OEP-Found.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Imported functions:<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-Found.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/IAT-Found.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>Excellent. The final thing we need to do, is put the reconstructed IAT back into the unpacked binary.<\/p>\n<p>This can be done by selecting the \u201cFix Dump\u201d option. Choosing our previously dumped file, the program will create a copy of it with the proper IAT table. You can always verify the file by running it. Also back on the debugger, the new created file will have the import table proper listed.<\/p>\n<p><a href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/Restored-IAT.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/Restored-IAT.jpg\" alt=\"\" width=\"540\" height=\"405\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Rebuilding IAT under IDA pro<\/h4>\n<p>An interesting approach with IDA pro was presented at Blackhat \u201809 by Jason Raber and Brian Krumheur (\u201c<a href=\"https:\/\/www.blackhat.com\/presentations\/bh-dc-09\/Krumheuer_Raber\/BlackHat-DC-09-Krumheuer-Raber-QuietRIATT-WhitePaper.pdf\" target=\"_blank\" rel=\"noopener\">QuietRIATT<\/a>\u201d).<\/p>\n<p>They demonstrated a plugin they wrote for IDA which allows them to rebuild the Import Address Table using hooked DLL calls.<\/p>\n<p>Unfortunately, today, this tool remains on a \u201crequest to have\u201d basis and from what we can know it is not yet a complete replacement for ImpREC that we used earlier.<\/p>\n<p>Using IDA pro is tricky for IAT rebuild. Since I don't have a copy of QuietRIATT myself, I will demonstrate an alternative way based on a script written by ekse, a member of the Corelan Team. You can download a copy of the script here : <a href=\"http:\/\/web.archive.org\/web\/20121018201921\/http:\/\/redmine.corelan.be\/projects\/ida-scripts\">http:\/\/redmine.corelan.be\/projects\/ida-scripts<\/a> (files - ida_patch_import.Py )<\/p>\n<p>The script will take the import table the way it\u2019s generated in Ollydbg and will create the names and xrefs back in IDA.<\/p>\n<p>Start with loading the packed executable in Ollydbg,<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/1.Back-to-olly1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0pt;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/1.Back-to-olly_thumb1.jpg\" alt=\"1.Back to olly\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>Simply run the routine we did earlier on, basically let the unpacker routine run and break at the end of the routine (the jump that would take us to the unpacked code).<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/2.Back-to-olly-bkp1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0pt;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/2.Back-to-olly-bkp_thumb1.jpg\" alt=\"2.Back to olly bkp\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>At that point, from there, step once (press F8 once). We can now see things in memory that were not visible before, since our application is unpacked at this point, and references to functions are restored.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/3.unpacked-in-memory1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0pt;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/3.unpacked-in-memory_thumb1.jpg\" alt=\"3.unpacked in memory\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>In order to get a dump of the current function state ( an actual IAT reference ) we select the first visible function location and with right click on that instruction, we choose \u201cFollow in dump \u2013 &gt; Memory address\u201d.<\/p>\n<p>This should get you all names of the functions properly<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/4.follow-in-dump1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0pt;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/4.follow-in-dump_thumb1.jpg\" alt=\"4.follow in dump\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>Right click on the section, go to \u201cCopy\u201d, choose \"select all\" and then \"Copy to file\".<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/5.save-IAT1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0pt;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/5.save-IAT_thumb1.jpg\" alt=\"5.save IAT\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>Save the table to file.<\/p>\n<p>&nbsp;<\/p>\n<p>Fire up IDA and open the same packed executable. Obviously, since it's packed, we're not going to see any references to functions names .<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/6.IAT-names-unknown1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0pt;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/6.IAT-names-unknown_thumb1.jpg\" alt=\"6.IAT names unknown\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>Simply run the python script:<\/p>\n<p>Edit - Plugins - IDA Python - find\/select the ida_patch_imports.py file.<\/p>\n<p>Feed it the text file that we created a few moments ago in Ollydbg, and that should restore the IAT in IDA.<\/p>\n<p><a class=\"thickbox\" href=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/7.IAT-names-restored1.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 7px; padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;\" src=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/12\/7.IAT-names-restored_thumb1.jpg\" alt=\"7.IAT names restored\" width=\"540\" height=\"405\" border=\"0\" \/><\/a><\/p>\n<p>Note : if IDA complains about \"Can't rename byte as 'function name' because this byte can't have a name (it's a tail byte).\", then before running the script, select the first 2 lines in the IDA View, and press \"u\" (undefine).<\/p>\n<p>Many thanks to corelanc0d3r for his support and tolerance and ekse for the excellent script.<\/p>\n<p>&nbsp;<\/p>\n<h3>About the author:<\/h3>\n<p><a href=\"https:\/\/twitter.com\/Dinosn\" target=\"_blank\" rel=\"noopener\">Nicolas Krassas<\/a> is a security researcher and system administrator. Consulting for security firms and ISPs, enjoys spending time reading topics on security, malware reversing and exploit writing.<\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>A few days ago a friend approached me and asked how he could see the import address table under immunity debugger and if this could be done using the command line.  <\/p>\n<p>I figured this would be a good time to take a look at what the IAT is, how we can list the IAT and what common reversing hurdles could be with regards to the IAT.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[2561],"tags":[3740,2802,2676,2581,2128,1978,285,261],"class_list":["post-7609","post","type-post","status-publish","format-standard","hentry","category-malware-and-reversing","tag-backup-restore","tag-mona-py","tag-reverse-engineering","tag-iat","tag-immunity-debugger","tag-python","tag-windbg","tag-corelan"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Many roads to IAT - Corelan | Exploit Development &amp; Vulnerability Research<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Many roads to IAT - Corelan | Exploit Development &amp; Vulnerability Research\" \/>\n<meta property=\"og:description\" content=\"A few days ago a friend approached me and asked how he could see the import address table under immunity debugger and if this could be done using the command line.  I figured this would be a good time to take a look at what the IAT is, how we can list the IAT and what common reversing hurdles could be with regards to the IAT.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/\" \/>\n<meta property=\"og:site_name\" content=\"Corelan | Exploit Development &amp; Vulnerability Research\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/corelanconsulting\" \/>\n<meta property=\"article:published_time\" content=\"2011-12-01T11:20:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg\" \/>\n<meta name=\"author\" content=\"Dinos\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@corelanc0d3r\" \/>\n<meta name=\"twitter:site\" content=\"@corelanc0d3r\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/\"},\"author\":{\"name\":\"Dinos\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/person\\\/a709d165acff65198466e057149e27b7\"},\"headline\":\"Many roads to IAT\",\"datePublished\":\"2011-12-01T11:20:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/\"},\"wordCount\":2539,\"publisher\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/10\\\/windbg1.jpg\",\"keywords\":[\"backup restore\",\"mona.py\",\"reverse engineering\",\"iat\",\"immunity debugger\",\"python\",\"windbg\",\"corelan\"],\"articleSection\":[\"Malware and Reversing\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/\",\"name\":\"Many roads to IAT - Corelan | Exploit Development &amp; Vulnerability Research\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/10\\\/windbg1.jpg\",\"datePublished\":\"2011-12-01T11:20:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/10\\\/windbg1.jpg\",\"contentUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2011\\\/10\\\/windbg1.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/2011\\\/12\\\/01\\\/roads-iat\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.corelan.be\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Many roads to IAT\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#website\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/\",\"name\":\"Corelan CyberSecurity Research\",\"description\":\"Corelan publishes in-depth tutorials on exploit development, Windows exploitation, vulnerability research, heap internals, reverse engineering and security tooling used by professionals worldwide.\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.corelan.be\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#organization\",\"name\":\"Corelan CyberSecurity Research\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/corelanlogo2_small-20.png\",\"contentUrl\":\"https:\\\/\\\/www.corelan.be\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/corelanlogo2_small-20.png\",\"width\":200,\"height\":200,\"caption\":\"Corelan CyberSecurity Research\"},\"image\":{\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/corelanconsulting\",\"https:\\\/\\\/x.com\\\/corelanc0d3r\",\"https:\\\/\\\/x.com\\\/corelanconsulting\",\"https:\\\/\\\/instagram.com\\\/corelanconsult\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.corelan.be\\\/#\\\/schema\\\/person\\\/a709d165acff65198466e057149e27b7\",\"name\":\"Dinos\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b94bb75d729c865abafc736374c9c8db004e6ecb5ade34a89cfaef3e99ba32e6?s=96&d=mm&r=x\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b94bb75d729c865abafc736374c9c8db004e6ecb5ade34a89cfaef3e99ba32e6?s=96&d=mm&r=x\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b94bb75d729c865abafc736374c9c8db004e6ecb5ade34a89cfaef3e99ba32e6?s=96&d=mm&r=x\",\"caption\":\"Dinos\"},\"url\":\"https:\\\/\\\/www.corelan.be\\\/index.php\\\/author\\\/dinos\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Many roads to IAT - Corelan | Exploit Development &amp; Vulnerability Research","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/","og_locale":"en_US","og_type":"article","og_title":"Many roads to IAT - Corelan | Exploit Development &amp; Vulnerability Research","og_description":"A few days ago a friend approached me and asked how he could see the import address table under immunity debugger and if this could be done using the command line.  I figured this would be a good time to take a look at what the IAT is, how we can list the IAT and what common reversing hurdles could be with regards to the IAT.","og_url":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/","og_site_name":"Corelan | Exploit Development &amp; Vulnerability Research","article_publisher":"https:\/\/www.facebook.com\/corelanconsulting","article_published_time":"2011-12-01T11:20:48+00:00","og_image":[{"url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg","type":"","width":"","height":""}],"author":"Dinos","twitter_card":"summary_large_image","twitter_creator":"@corelanc0d3r","twitter_site":"@corelanc0d3r","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#article","isPartOf":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/"},"author":{"name":"Dinos","@id":"https:\/\/www.corelan.be\/#\/schema\/person\/a709d165acff65198466e057149e27b7"},"headline":"Many roads to IAT","datePublished":"2011-12-01T11:20:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/"},"wordCount":2539,"publisher":{"@id":"https:\/\/www.corelan.be\/#organization"},"image":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#primaryimage"},"thumbnailUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg","keywords":["backup restore","mona.py","reverse engineering","iat","immunity debugger","python","windbg","corelan"],"articleSection":["Malware and Reversing"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/","url":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/","name":"Many roads to IAT - Corelan | Exploit Development &amp; Vulnerability Research","isPartOf":{"@id":"https:\/\/www.corelan.be\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#primaryimage"},"image":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#primaryimage"},"thumbnailUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg","datePublished":"2011-12-01T11:20:48+00:00","breadcrumb":{"@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#primaryimage","url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg","contentUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2011\/10\/windbg1.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.corelan.be\/index.php\/2011\/12\/01\/roads-iat\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.corelan.be\/"},{"@type":"ListItem","position":2,"name":"Many roads to IAT"}]},{"@type":"WebSite","@id":"https:\/\/www.corelan.be\/#website","url":"https:\/\/www.corelan.be\/","name":"Corelan CyberSecurity Research","description":"Corelan publishes in-depth tutorials on exploit development, Windows exploitation, vulnerability research, heap internals, reverse engineering and security tooling used by professionals worldwide.","publisher":{"@id":"https:\/\/www.corelan.be\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.corelan.be\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.corelan.be\/#organization","name":"Corelan CyberSecurity Research","url":"https:\/\/www.corelan.be\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.corelan.be\/#\/schema\/logo\/image\/","url":"https:\/\/www.corelan.be\/wp-content\/uploads\/2026\/03\/corelanlogo2_small-20.png","contentUrl":"https:\/\/www.corelan.be\/wp-content\/uploads\/2026\/03\/corelanlogo2_small-20.png","width":200,"height":200,"caption":"Corelan CyberSecurity Research"},"image":{"@id":"https:\/\/www.corelan.be\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/corelanconsulting","https:\/\/x.com\/corelanc0d3r","https:\/\/x.com\/corelanconsulting","https:\/\/instagram.com\/corelanconsult"]},{"@type":"Person","@id":"https:\/\/www.corelan.be\/#\/schema\/person\/a709d165acff65198466e057149e27b7","name":"Dinos","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b94bb75d729c865abafc736374c9c8db004e6ecb5ade34a89cfaef3e99ba32e6?s=96&d=mm&r=x","url":"https:\/\/secure.gravatar.com\/avatar\/b94bb75d729c865abafc736374c9c8db004e6ecb5ade34a89cfaef3e99ba32e6?s=96&d=mm&r=x","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b94bb75d729c865abafc736374c9c8db004e6ecb5ade34a89cfaef3e99ba32e6?s=96&d=mm&r=x","caption":"Dinos"},"url":"https:\/\/www.corelan.be\/index.php\/author\/dinos\/"}]}},"views":25656,"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts\/7609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/comments?post=7609"}],"version-history":[{"count":0,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/posts\/7609\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/media?parent=7609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/categories?post=7609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.corelan.be\/index.php\/wp-json\/wp\/v2\/tags?post=7609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}