PEDump小工具

编写PEDump,读取内容跟FlexHex的显示格式差不多

  1. .386
  2. .model flat,stdcall
  3. option casemap:none
  4.  
  5. include windows.inc
  6. include user32.inc
  7. includelib user32.lib
  8. include kernel32.inc
  9. includelib kernel32.lib
  10. include comdlg32.inc
  11. includelib comdlg32.lib
  12.  
  13.  
  14. ICO_MAIN equ 1000
  15. DLG_MAIN equ 1000
  16. IDC_INFO equ 1001
  17. IDM_MAIN equ 2000
  18. IDM_OPEN equ 2001
  19. IDM_EXIT equ 2002
  20. IDM_1 equ 4000
  21. IDM_2 equ 4001
  22. IDM_3 equ 4002
  23.  
  24. .data
  25. hInstance dd ? ; 进程句柄
  26. hRichEdit dd ?
  27. hWinMain dd ? ; 弹出窗口句柄
  28. hWinEdit dd ? ; 富文本框句柄
  29. totalSize dd ? ; 文件大小
  30. lpMemory dd ? ; 内存映像文件在内存的起始位置
  31. szFileName db MAX_PATH dup(?) ;要打开的文件路径及名称名
  32.  
  33. lpServicesBuffer db 100 dup(0) ;所有内容
  34. bufDisplay db 50 dup(0) ;第三列ASCII码字符显示
  35. szBuffer db 200 dup(0) ;临时缓冲区
  36. lpszFilterFmt4 db '%08x ',0
  37. lpszManyBlanks db ' ',0
  38. lpszBlank db ' ',0
  39. lpszSplit db '-',0
  40. lpszScanFmt db '%02x',0
  41. lpszHexArr db '0123456789ABCDEF',0
  42. lpszReturn db 0dh,0ah,0
  43. lpszDoubleReturn db 0dh,0ah,0dh,0ah,0
  44. lpszOut1 db '文件大小:%d',0
  45. dwStop dd 0
  46. .const
  47. szDllEdit db 'RichEd20.dll',0
  48. szClassEdit db 'RichEdit20A',0
  49. szFont db '宋体',0
  50. szExtPe db 'PE File',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
  51. db 'All Files(*.*)',0,'*.*',0,0
  52. szErr db '文件格式错误!',0
  53. szErrFormat db '操作文件时出现错误!',0
  54.  
  55.  
  56. .code
  57.  
  58. ;----------------
  59. ;初始化窗口程序
  60. ;----------------
  61. _init proc
  62. local @stCf:CHARFORMAT
  63.  
  64. invoke GetDlgItem,hWinMain,IDC_INFO
  65. mov hWinEdit,eax
  66. invoke LoadIcon,hInstance,ICO_MAIN
  67. invoke SendMessage,hWinMain,WM_SETICON,ICON_BIG,eax ;为窗口设置图标
  68. invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0 ;设置编辑控件
  69. invoke RtlZeroMemory,addr @stCf,sizeof @stCf
  70. mov @stCf.cbSize,sizeof @stCf
  71. mov @stCf.yHeight,14*1440/96
  72. mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
  73. invoke lstrcpy,addr @stCf.szFaceName,addr szFont
  74. invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
  75. invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
  76. ret
  77. _init endp
  78.  
  79. ;------------------
  80. ; 错误Handler
  81. ;------------------
  82. _Handler proc _lpExceptionRecord,_lpSEH,\
  83. _lpContext,_lpDispathcerContext
  84.  
  85. pushad
  86. mov esi,_lpExceptionRecord
  87. mov edi,_lpContext
  88. assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
  89. mov eax,_lpSEH
  90. push [eax+0ch]
  91. pop [edi].regEbp
  92. push [eax+8]
  93. pop [edi].regEip
  94. push eax
  95. pop [edi].regEsp
  96. assume esi:nothing,edi:nothing
  97. popad
  98. mov eax,ExceptionContinueExecution
  99. ret
  100. _Handler endp
  101.  
  102. ;---------------------
  103. ; 往文本框中追加文本
  104. ;---------------------
  105. _appendInfo proc _lpsz
  106. local @stCR:CHARRANGE
  107.  
  108. pushad
  109. invoke GetWindowTextLength,hWinEdit
  110. mov @stCR.cpMin,eax ;将插入点移动到最后
  111. mov @stCR.cpMax,eax
  112. invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stCR
  113. invoke SendMessage,hWinEdit,EM_REPLACESEL,FALSE,_lpsz
  114. popad
  115. ret
  116. _appendInfo endp
  117.  
  118.  
  119. ;--------------------
  120. ; 打开PE文件并处理
  121. ;--------------------
  122. _openFile proc
  123. local @stOF:OPENFILENAME
  124. local @hFile,@hMapFile
  125. local @bufTemp1 ; 十六进制字节码
  126. local @bufTemp2 ; 第一列
  127. local @dwCount ; 计数,逢16则重新计
  128. local @dwCount1 ; 地址顺号
  129. local @dwBlanks ; 最后一行空格数
  130.  
  131. invoke RtlZeroMemory,addr @stOF,sizeof @stOF
  132. mov @stOF.lStructSize,sizeof @stOF
  133. push hWinMain
  134. pop @stOF.hwndOwner
  135. mov @stOF.lpstrFilter,offset szExtPe
  136. mov @stOF.lpstrFile,offset szFileName
  137. mov @stOF.nMaxFile,MAX_PATH
  138. mov @stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST
  139. invoke GetOpenFileName,addr @stOF ;让用户选择打开的文件
  140. .if !eax
  141. jmp @F
  142. .endif
  143. invoke CreateFile,addr szFileName,GENERIC_READ,\
  144. FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,\
  145. OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
  146. .if eax!=INVALID_HANDLE_VALUE
  147. mov @hFile,eax
  148. invoke GetFileSize,eax,NULL ;获取文件大小
  149. mov totalSize,eax
  150.  
  151. .if eax
  152. invoke CreateFileMapping,@hFile,\ ;内存映射文件
  153. NULL,PAGE_READONLY,0,0,NULL
  154. .if eax
  155. mov @hMapFile,eax
  156. invoke MapViewOfFile,eax,\
  157. FILE_MAP_READ,0,0,0
  158. .if eax
  159. mov lpMemory,eax ;获得文件在内存的映象起始位置
  160. assume fs:nothing
  161. push ebp
  162. push offset _ErrFormat
  163. push offset _Handler
  164. push fs:[0]
  165. mov fs:[0],esp
  166.  
  167. ;开始处理文件
  168.  
  169. ;缓冲区初始化
  170. invoke RtlZeroMemory,addr @bufTemp1,10
  171. invoke RtlZeroMemory,addr @bufTemp2,20
  172. invoke RtlZeroMemory,addr lpServicesBuffer,100
  173. invoke RtlZeroMemory,addr bufDisplay,50
  174.  
  175. mov @dwCount,1
  176. mov esi,lpMemory
  177. mov edi,offset bufDisplay
  178.  
  179. ; 将第一列写入lpServicesBuffer
  180. mov @dwCount1,0
  181. invoke wsprintf,addr @bufTemp2,addr lpszFilterFmt4,@dwCount1
  182. invoke lstrcat,addr lpServicesBuffer,addr @bufTemp2
  183.  
  184. ;求最后一行的空格数(16-长度%16)*3
  185. xor edx,edx
  186. mov eax,totalSize
  187. mov ecx,16
  188. div ecx
  189. mov eax,16
  190. sub eax,edx
  191. xor edx,edx
  192. mov ecx,3
  193. mul ecx
  194. mov @dwBlanks,eax
  195.  
  196. ;invoke wsprintf,addr szBuffer,addr lpszOut1,totalSize
  197. ;invoke MessageBox,NULL,addr szBuffer,NULL,MB_OK
  198.  
  199. .while TRUE
  200. .if totalSize==0 ;最后一行
  201. ;填充空格
  202. .while TRUE
  203. .break .if @dwBlanks==0
  204. invoke lstrcat,addr lpServicesBuffer,addr lpszBlank
  205. dec @dwBlanks
  206. .endw
  207. ;第二列与第三列中间的空格
  208. invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
  209. ;第三列内容
  210. invoke lstrcat,addr lpServicesBuffer,addr bufDisplay
  211. ;回车换行符号
  212. invoke lstrcat,addr lpServicesBuffer,addr lpszReturn
  213. .break
  214. .endif
  215. ;将al翻译成可以显示的ascii码字符,注意不能破坏al的值
  216. mov al,byte ptr [esi]
  217. .if al>20h && al<7eh
  218. mov ah,al
  219. .else ;如果不是ASCII码值,则显示“.”
  220. mov ah,2Eh
  221. .endif
  222. ;写入第三列的值
  223. mov byte ptr [edi],ah
  224.  
  225. ;win2k不支持al字节级别,经常导致程序无故结束,
  226. ;因此用以下方法替代
  227. ;invoke wsprintf,addr @bufTemp1,addr lpszFilterFmt3,al
  228.  
  229. mov bl,al
  230. xor edx,edx
  231. xor eax,eax
  232. mov al,bl
  233. mov cx,16
  234. div cx ;结果高位在al中,余数在dl中
  235.  
  236. ;组合字节的十六进制字符串到@bufTemp1中,类似于:“7F \0”
  237. push edi
  238. xor bx,bx
  239. mov bl,al
  240. movzx edi,bx
  241. mov bl,byte ptr lpszHexArr[edi]
  242. mov byte ptr @bufTemp1[0],bl
  243.  
  244. xor bx,bx
  245. mov bl,dl
  246. movzx edi,bx
  247. mov bl,byte ptr lpszHexArr[edi]
  248. mov byte ptr @bufTemp1[1],bl
  249. mov bl,20h
  250. mov byte ptr @bufTemp1[2],bl
  251. mov bl,0
  252. mov byte ptr @bufTemp1[3],bl
  253. pop edi
  254.  
  255. ; 将第二列写入lpServicesBuffer
  256. invoke lstrcat,addr lpServicesBuffer,addr @bufTemp1
  257.  
  258. .if @dwCount==16 ;已到16个字节,
  259. ;第二列与第三列中间的空格
  260. invoke lstrcat,addr lpServicesBuffer,addr lpszManyBlanks
  261. ;显示第三列字符
  262. invoke lstrcat,addr lpServicesBuffer,addr bufDisplay
  263. ;回车换行
  264. invoke lstrcat,addr lpServicesBuffer,addr lpszReturn
  265.  
  266. ;写入内容
  267. invoke _appendInfo,addr lpServicesBuffer
  268. invoke RtlZeroMemory,addr lpServicesBuffer,100
  269.  
  270. .break .if dwStop==1
  271.  
  272. ;显示下一行的地址
  273. inc @dwCount1
  274. invoke wsprintf,addr @bufTemp2,addr lpszFilterFmt4,\
  275. @dwCount1
  276. invoke lstrcat,addr lpServicesBuffer,addr @bufTemp2
  277. dec @dwCount1
  278.  
  279. mov @dwCount,0
  280. invoke RtlZeroMemory,addr bufDisplay,50
  281. mov edi,offset bufDisplay
  282. ;为了能和后面的inc edi配合使edi正确定位到bufDisplay处
  283. dec edi
  284. .endif
  285.  
  286. dec totalSize
  287. inc @dwCount
  288. inc esi
  289. inc edi
  290. inc @dwCount1
  291. .endw
  292.  
  293. ;添加最后一行
  294. invoke _appendInfo,addr lpServicesBuffer
  295.  
  296.  
  297. ;处理文件结束
  298.  
  299. jmp _ErrorExit
  300.  
  301. _ErrFormat:
  302. invoke MessageBox,hWinMain,offset szErrFormat,NULL,MB_OK
  303. _ErrorExit:
  304. pop fs:[0]
  305. add esp,0ch
  306. invoke UnmapViewOfFile,lpMemory
  307. .endif
  308. invoke CloseHandle,@hMapFile
  309. .endif
  310. invoke CloseHandle,@hFile
  311. .endif
  312. .endif
  313. @@:
  314. ret
  315. _openFile endp
  316. ;-------------------
  317. ; 窗口程序
  318. ;-------------------
  319. _ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
  320. local @sClient
  321.  
  322. mov eax,wMsg
  323. .if eax==WM_CLOSE
  324. invoke EndDialog,hWnd,NULL
  325. .elseif eax==WM_INITDIALOG ;初始化
  326. push hWnd
  327. pop hWinMain
  328. call _init
  329. .elseif eax==WM_COMMAND ;菜单
  330. mov eax,wParam
  331. .if eax==IDM_EXIT ;退出
  332. invoke EndDialog,hWnd,NULL
  333. .elseif eax==IDM_OPEN ;打开文件
  334. mov dwStop,0
  335. invoke CreateThread,NULL,0,addr _openFile,addr @sClient,0,NULL
  336. ;invoke _openFile
  337. .elseif eax==IDM_1
  338. mov dwStop,1
  339. .elseif eax==IDM_2
  340. .elseif eax==IDM_3
  341. .endif
  342. .else
  343. mov eax,FALSE
  344. ret
  345. .endif
  346. mov eax,TRUE
  347. ret
  348. _ProcDlgMain endp
  349.  
  350. start:
  351. invoke LoadLibrary,offset szDllEdit
  352. mov hRichEdit,eax
  353. invoke GetModuleHandle,NULL
  354. mov hInstance,eax
  355. invoke DialogBoxParam,hInstance,\
  356. DLG_MAIN,NULL,offset _ProcDlgMain,NULL
  357. invoke FreeLibrary,hRichEdit
  358. invoke ExitProcess,NULL
  359. end start

编译ASM生成OBJ

ml -c -coff pedump.asm

链接pe.res pedump.obj生成pedump.exe

link -subsystem:windows pedump.obj pe.res

发表评论

邮箱地址不会被公开。 必填项已用*标注