• 标 题:我写的一个内存补丁,很基本。。高手莫入。。 (5千字)
  • 作 者:Spring.W
  • 时 间:2002-10-20 16:49:07
  • 链 接:http://bbs.pediy.com

某个软件因为有壳,在将壳部分仿真完成后,发现还需要对某个地址SMC,故在解压缩完成后,
将要跳到真正入口处时,先跳到SMC处执行补丁,然后再跳到真正入口处。采用了增加一个节
的方法扩充SMC代码(怎样增加一个节,因为很简单,不再做说明)
  为什么不直接脱壳呢?因为这是个DLL,脱壳很麻烦的,要处理引入表、冲定位项,干脆仿真
通过算了,这样的问题是要修改某个内存地址的时候,需要用SMC,不能直接修改了。。

--------------------------------------------------------------------------------
//要修改的地址Address=1067206h-00029302h=103DF04h开始的5字节
//要修改的地址将以1067206h作为基准,因为这个基准地址我们可以很容易得到且不受任何
//因素影响,上面为什么使用“-”,因为我将节加到最后,地址肯定大于原程序中的任何地
//址。
--------------------------------------------------------------------------------
//补丁程序
//1.因为原来程序引入表中没有"VirtualQuery"函数,所以要先取得
//2.以下用到的其它函数,原来程序引入表中都有,所以直接使用
--------------------------------------------------------------------------------
EAX=00000000  EBX=01067012  ECX=00000000  EDX=01030000  ESI=00000004       
EDI=FFFFFFFC  EBP=01067206  ESP=016FFBC0  EIP=0106720F  o d I s z a P c   
CS=0167  DS=016F  SS=016F  ES=016F  FS=3C8F  GS=0000                     
--------------------------------------------------------------------------------
016F:01066FE2 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
016F:01066FF2 00 00 00 00 00 00 00 00-00 00 00 00 00 00 E9 FB  ................
016F:01067002 01 00 00 56 69 72 74 75-61 6C 51 75 65 72 79 00  ...VirtualQuery.
016F:01067012 4B 65 72 6E 65 6C 33 32-2E 44 4C 4C 00 00 00 00  Kernel32.DLL....
016F:01067022 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
016F:01067032 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
--------------------------------------------------------------------------------
0167:01067200  PUSHAD
0167:01067201  CALL      01067206
0167:01067206  POP      EBP          ;此时,ebp = 1067206h
0167:01067207  MOV      EBX,EBP
0167:01067209  SUB      EBX,000001F4  ;EBX-1F4h = "Kernel32.DLL"
0167:0106720F  PUSH      EBX
0167:01067210  CALL      [KERNEL32!GetModuleHandleA]
0167:01067216  TEST      EAX,EAX
0167:01067218  JZ        010672AC
0167:0106721E  MOV      EDX,EAX
0167:01067220  MOV      EBX,EBP
0167:01067222  SUB      EBX,00000201  ;EBX-201h 指向"VirtualQuery"
0167:01067228  PUSH      EBX
0167:01067229  PUSH      EDX
0167:0106722A  NOP
0167:0106722B  NOP
0167:0106722C  NOP
0167:0106722D  NOP
0167:0106722E  NOP
0167:0106722F  NOP
//
0167:01067230  CALL      [KERNEL32!GetProcAddress] ;取得VirtualQuery函数地址
0167:01067236  TEST      EAX,EAX
0167:01067238  JZ        010672AC
0167:0106723A  MOV      EBX,EBP
0167:0106723C  SUB      EBX,00000106 ;EBX-106h 指向 VirtualQuery函数参数区(参数设置参考SDK)
0167:01067242  PUSH      1C          ;VirtualQuery函数参数区长度
0167:01067244  PUSH      EBX          ;PMEMORY_BASIC_INFORMATION
0167:01067245  MOV      EBX,EBP
0167:01067247  SUB      EBX,00029302 ;要修改的地址Address=EBX-00029302h=103DF04h
0167:0106724D  PUSH      EBX          ;address of region
0167:0106724E  CALL      EAX          ;调用VirtualQuery取得Address所属页的页基址
//
0167:01067250  MOV      EBX,EBP
0167:01067252  SUB      EBX,000001E6 ;EBX-1e6h = VirtualProtect参数,返回的原来的页属性
0167:01067258  PUSH      EBX
0167:01067259  PUSH      00000040    ;新的页属性(PAGE_EXECUTE_READWRITE)
0167:0106725E  MOV      EBX,EBP
0167:01067260  SUB      EBX,00000106         ;EBX-106h = VirtualProtect参数区,数据来自VirtualQuery
0167:01067266  PUSH      DWORD PTR [EBX+0C] ;VirtualProtect参数,size of the region
0167:01067269  PUSH      DWORD PTR [EBX]    ;VirtualProtect参数,address of region of committed
                                            ;pages
0167:0106726B  NOP
0167:0106726C  NOP
0167:0106726D  NOP
0167:0106726E  CALL      [KERNEL32!VirtualProtect] ;调用VirtualProtect改变页属性
0167:01067274  MOV      EBX,EBP
0167:01067276  SUB      EBX,00029302  ;要修改的地址Address=EBX-00029302h=103DF04h
0167:0106727C  MOV      DWORD PTR [EBX],b3b2b1b0  ;将原来4字节改为b3b2b1b0
0167:01067282  MOV      BYTE PTR [EBX+04],XX      ;将原来1字节改为XXh

//下面恢复修改的页属性
0167:01067286  MOV      EBX,EBP
0167:01067288  SUB      EBX,000001E4  ;VirtualProtect参数,原来的页属性,此时这个参数对
                                      ;我们没用,但必须有
0167:0106728E  PUSH      EBX
0167:0106728F  MOV      EBX,EBP
0167:01067291  SUB      EBX,000001E6  ;保存的原来的页属性
0167:01067297  PUSH      DWORD PTR [EBX]
0167:01067299  MOV      EBX,EBP
0167:0106729B  SUB      EBX,00000106          ;EBX-106h = VirtualProtect参数区,数据来自VirtualQuery
0167:010672A1  PUSH      DWORD PTR [EBX+0C] ;VirtualProtect参数,size of the region
0167:010672A4  PUSH      DWORD PTR [EBX]    ;VirtualProtect参数,address of region of committed
                                            ;pages
0167:010672A6  CALL      [KERNEL32!VirtualProtect]  ;调用VirtualProtect恢复页属性
0167:010672AC  POPAD
0167:010672AD  JMP      XXXXXXXX        ;跳转到原来程序处继续执行


  因为涉及某个国产软件,恕不说明具体程序。。。
                                Spring.W
                                2002/10/20