; PE dump snippet by David "Saturn" van Moolenbroek ; Version 0.03, released 30-05-2021 -- support on #help.script/QuakeNet ; ; History: ; 0.03 (30-05-2021): ; - fix bug printing imported ordinals ; 0.02 (23-12-2019): ; - work around mIRC bug for printing imported names vs ordinals ; - print not just names but also ordinals for exported symbols ; 0.01 (20-03-2006): ; - initial version ; ; Usage: /pedump ; ; This command dumps the import and export tables of an EXE or DLL. alias -l rva2off { ; $1 = section header offset, $2 = section end, $3 = requested RVA var %off = $1 ; loop through the sections, looking for a matching range for the RVA while (%off < $2) { var %rvastart = $bvar(&d,$calc(%off + 12)).long var %rvaend = %rvastart + $bvar(&d,$calc(%off + 8)).long if ($3 >= %rvastart) && ($3 < %rvaend) { var %filestart = $bvar(&d,$calc(%off + 20)).long return $calc($3 - %rvastart + %filestart + 1) } inc %off 40 } } alias -l rva2str if ($rva2off($1,$2,$3)) return $bvar(&d,$v1,800).text alias pedump { ; load the file and see if there's a MZ header bread $qt($1-) 0 $file($1-).size &d if ($bvar(&d,1,2).text != MZ) return ; get the offset of the PE header var %pe = 1 + $bvar(&d,61).long if ($bvar(&d,%pe,2).text != PE) return ; get offsets for the start and end of the array of sections var %ss = $calc(%pe + 24 + $bvar(&d,$calc(%pe + 20)).word) var %se = $calc(%ss + 40 * $bvar(&d,$calc(%pe + 6)).word) linesep ; dump the import table var %imp = $rva2off(%ss,%se,$bvar(&d,$calc(%pe + 128)).long) while ($bvar(&d,%imp).long) || ($bvar(&d,$calc(%imp + 16)).long) { var %thunk = $rva2off(%ss,%se,$v1) echo -ag Imports from $rva2str(%ss,%se,$bvar(&d,$calc(%imp + 12)).long) while ($bvar(&d,%thunk).long) { var %val = $v1 if ($isbit(%val,32)) echo -ag -> $chr(35) $+ $bitoff(%val,32) else echo -ag -> $rva2str(%ss,%se,$calc(%val + 2)) inc %thunk 4 } inc %imp 20 } ; dump the export table var %exp = $rva2off(%ss,%se,$bvar(&d,$calc(%pe + 120)).long) if (%exp) { echo -ag Exports from $rva2str(%ss,%se,$bvar(&d,$calc(%exp + 12)).long) var %off = $rva2off(%ss,%se,$bvar(&d,$calc(%exp + 32)).long) var %ordbase = $bvar(&d,$calc(%exp + 16)) var %ordoff = $rva2off(%ss,%se,$bvar(&d,$calc(%exp + 36)).long) var %end = $calc(%off + 4 * $bvar(&d,$calc(%exp + 24)).long) while (%off < %end) { echo -ag <- $rva2str(%ss,%se,$bvar(&d,%off).long) ( $+ $chr(35) $+ $calc(%ordbase + $bvar(&d,%ordoff).word) $+ ) inc %off 4 inc %ordoff 2 } } }