飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 1722|回复: 3

大家好!新人求助

[复制链接]

该用户从未签到

发表于 2006-6-23 15:27:46 | 显示全部楼层 |阅读模式
提示: 作者被禁止或删除 内容自动屏蔽
PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-8-5 08:23
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2006-6-23 15:49:10 | 显示全部楼层
    pelock1.0的:

    标 题: PELock 1.0x -> Bartosz Wojcik简单脱壳
    发帖人:aki
    时 间: 2005-06-05 09:18
    原文链接:http://bbs.pediy.com/showthread.php?threadid=14253
    详细信息:


    PELock 1.0x -> Bartosz Wojcik简单脱壳
    最近碰到PELock 1.0x -> Bartosz Wojcik的壳,以前没见过,索性研究了一下。
    准备工作,忽略除内存异常外的其他异常。11次异常程序运行。
    脱这个壳主要是要解决三个问题。
    1:输入表。程序的输入表被替换到壳中去了。
    00374661  MOV DWORD PTR DS:[ECX],EBX
    00374663  JMP SHORT 00374668
    EBX中指向壳的地址,EAX为api的地址。直接改EBX为EAX的话后面的crc校验会出错。所以要想改就要先搞定crc。jingulong大虾给了一段代码,不过本人比较懒,用的是fxyang的script,速度有点慢,两三分钟才解出整个输入表
    =======================================
    //获取iat表Script
    //by  fxyang  2005.5.20
    //由于只想得到iat表,所以没有检查表的结束。
    var index
    #LOG

    gpa "LoadLibraryA", "kernel32.dll"
    bprm $RESULT,1
    mov index,1
    eob exp1
    run

    exp1:
    cmp index,0
    je exp2
    dec index
    esto

    exp2:
    bpmc
    rtu
    bprm 00374661,1
    mov index,1
    eob exp3
    esto

    exp3:
    cmp index,0
    je exp4
    dec index
    esto

    exp4:
    mov [ecx],eax
    add eip,2
    mov index,1
    esto
    =========================================
    2。搞定了输入表,接下来就是壳转移数据的问题了。
    用401000内存断点方法dump下来,修复一下后会出现这个问题
    00402814    $  53             push ebx
    00402815    .  85C0           test eax,eax
    00402817    .  7E 15          jle short dumped_.0040282E
    00402819    .- E9 FFDBE900    jmp 012A041D  //这里出错
    0040281E       00             db 00
    0040281F    .  8BD8           mov ebx,eax
    00402821    .  85DB           test ebx,ebx

    原来这个壳把程序的一部分参数和函数的调用都弄到了动态申请的地址,dump下来的程序当然没有这个地址了,跟踪一下源程序八次异常后来到处理上面数据的地方
    00378367     3017            xor byte ptr ds:[edi],dl       //特殊处理,edi放填充地址
    00378369     47              inc edi
    0037836A     8B16            mov edx,dword ptr ds:[esi]
    0037836C     83C6 04         add esi,4
    0037836F     C602 E9         mov byte ptr ds:[edx],0E9
    00378372     8BC7            mov eax,edi
    00378374     2BC2            sub eax,edx
    00378376     83E8 05         sub eax,5
    00378379     8942 01         mov dword ptr ds:[edx+1],eax
    0037837C     8A06            mov al,byte ptr ds:[esi]
    0037837E     46              inc esi
    0037837F     0FB6C8          movzx ecx,al
    00378382     83E0 03         and eax,3
    00378385     C1E9 02         shr ecx,2
    00378388     F3:A5           rep movs dword ptr es:[edi],dword ptr ds:[esi]
    0037838A     8BC8            mov ecx,eax
    0037838C     F3:A4           rep movs byte ptr es:[edi],byte ptr ds:[esi]
    0037838E     8A06            mov al,byte ptr ds:[esi]
    00378390     46              inc esi
    00378391     03D0            add edx,eax
    00378393     C607 E9         mov byte ptr ds:[edi],0E9
    00378396     2BD7            sub edx,edi
    00378398     83EA 05         sub edx,5
    0037839B     8957 01         mov dword ptr ds:[edi+1],edx
    0037839E     83C7 05         add edi,5
    003783A1     4B              dec ebx
    003783A2   ^ 75 C3           jnz short 00378367         //循环
    第一次循环的时候在 xor byte ptr ds:[edi],dl中的edi放的是代码被转移的起始地址,看一下edi是12A000,原版打算自己添加一个段然后把数据写入这个段里,但是添加失败了,郁闷!不过dump下来的程序的中有一个起始地址5d3000,大小为1c0000的段是空的,所以直接把edi的值改为5d3000即可。
    3。壳转移数据(二)
    运行修复了的程序,还是出错
    00480AD4     55               push ebp
    00480AD5     68 100C4800      push H_Client.00480C10
    00480ADA     64:FF30          push dword ptr fs:[eax]
    00480ADD     64:8920          mov dword ptr fs:[eax],esp
    00480AE0     A1 E4755C00      mov eax,dword ptr ds:[5C75E4]
    00480AE5     8B00             mov eax,dword ptr ds:[eax]
    00480AE7     8B10             mov edx,dword ptr ds:[eax]   //指向壳中
    00480AE9     FF52 14          call dword ptr ds:[edx+14]
    00480AEC     33C0             xor eax,eax
    跟踪原程序,发现有这么一个很长的表,程序会不断的从这个表中找调用数据
    00376C44  0102A50F
    00376C48  000000E9
    00376C4C  00000000
    00376C50  00406E3C  H_Client.00406E3C
    00376C54  00406E0C  H_Client.00406E0C
    00376C58  00406C30  H_Client.00406C30
    00376C5C  00406BDC  H_Client.00406BDC
    00376C60  00406F70  H_Client.00406F70
    00376C64  00406F40  H_Client.00406F40
    00376C68  00408094  H_Client.00408094
    00376C6C  00408064  H_Client.00408064
    这些数据跟壳是在一个段中的,但是单独把这些数据转移会出错,这个段的地址又小于基址,dump下这个段来也不好弄,搞了半天发现这个段的内存是动态申请的,重新来过,下he VitrualProtect
    断下后ctrl+f9返回,eax为370000,看了一下申请的大小要比1c0000小许多,干脆把eax改为5d3000,把这个壳整个调到5d3000段,然后第八个异常的时候再处理一下上面处理的数据
    00378367     3017            xor byte ptr ds:[edi],dl   
    改edi为5e0000
    最后修复下stolen code,纠正jmagesize后dump下来,修复输入表,ok
    总结一下:
    一,获取输入表
    二,修改VirtualProtect返回值,修改00378367处edi值,使这些数据可以被dump下来。
    三,修复stolen code,dump下来后修复输入表。
    by ak[BCG][DCM][DFCG]
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-8-5 08:23
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2006-6-23 15:50:05 | 显示全部楼层
    标 题: PELock1.0x脱壳实例
    发帖人:fxyang
    时 间: 2005-05-24 11:12
    原文链接:http://bbs.pediy.com/showthread.php?threadid=13924
    详细信息:


    PELock 1.0x -> Bartosz Wojcik脱壳实例之CryptCD Professional version 4.0.exe
    下载地址:http://bbs.hanzify.org/index.php ... e=post&id=14354

    1.借尸还魂--搞定iat表
    用OD加载CryptCD Professional version 4.0.exe
    OD的异常全部勾上,到壳的入口:
    0049D05C >JMP SHORT CryptCD_.0049D060  
    0049D05E  XCHG ESP,ESI
    0049D060  CLC
    0049D061  JNB SHORT CryptCD_.0049D064

    Alt+E打开模块窗口,光标选择kernel32 (system) Ctrl+N打开函数窗口
    找到LoadLibraryA这个函数,双击它:
    77E5D8B4 >CMP DWORD PTR SS:[ESP+4],0
    77E5D8B9  PUSH EBX
    77E5D8BA  PUSH ESI
    77E5D8BB  JE SHORT kernel32.77E5D8D6

    在77E5D8B9  PUSH EBX 这行下内存访问中断,F9运行程序:
    第二次中断在:
    00374CD9  MOV EDX,DWORD PTR DS:[ECX+ESI]
    00374CDC  JMP SHORT 00374CE1
    ......
    0037501D  MOV EAX,DWORD PTR DS:[ESI]
    0037501F  MOV EDX,EAX
    00375021  CMP AL,0CC
    00375023  JNZ SHORT 00375054
    ......
    00375B22  MOV AL,BYTE PTR DS:[ECX]
    00375B24  INC ECX
    00375B25  OR EDX,DWORD PTR DS:[EBX+EAX*4]
    00375B28  TEST DL,8
    00375B2B  JNZ SHORT 00375B1F




    壳会全程检查函数代码,所以int3中断不能使用。

    Shift+F9继续运行,直到重新被中断在函数中
    77E5D8B9  PUSH EBX
    77E5D8BA  PUSH ESI
    77E5D8BB  JE SHORT kernel32.77E5D8D6

    堆栈中出现:
    0012EA54   72F44841  返回到 72F44841 来自 kernel32.LoadLibraryA
    0012EA58   72F1A978  ASCII "gdi32.dll"



    回到壳代码中,F7运行到:
    00374661  MOV DWORD PTR DS:[ECX],EBX
    00374663  JMP SHORT 00374668


    EAX 77D18ABC USER32.TranslateMessage
    ECX 00426288 CryptCD_.00426288
    EDX 77D10000 USER32.77D10000
    EBX 003E193F
    ESP 0012FFAC
    EBP 0037062D
    ESI 00380399
    EDI 00380389 ASCII "USER32.dll"
    EIP 00374661

    分析代码发现,[ECX]是iat表中的地址,EBX是加密后的函数地址,再仔细分析发现,
    这时候的EAX中就是未加密的函数,如果把:

    00374661  MOV DWORD PTR DS:[ECX],EBX
    修改成:
    00374661  MOV DWORD PTR DS:[ECX],EAX

    嘿嘿就可以得到正确的iat表了,修改看看
    继续运行,出现Invalid version of library USER32.dll错误。是因为下面的CRC没有通过。

    没有关系,用OllyScript来搞定它:
    =======================================
    //PELock 1.0x 脱壳实例之CryptCD Professional version 4.0
    //获取iat表Script
    //by  fxyang  2005.5.20
    //由于只想得到iat表,所以没有检查表的结束。
    var index
    #LOG

    gpa "LoadLibraryA", "kernel32.dll"
    bprm $RESULT,1
    mov index,1
    eob exp1
    run

    exp1:
    cmp index,0
    je exp2
    dec index
    esto

    exp2:
    bpmc
    rtu
    bprm 00374661,1
    mov index,1
    eob exp3
    esto

    exp3:
    cmp index,0
    je exp4
    dec index
    esto

    exp4:
    mov [ecx],eax
    add eip,2
    mov index,1
    esto
    =========================================

    脚本完成后到iat表中看看:
    00426000  D8 17 DA 77 9A 22 DA 77  ?趙?趙
    00426008  68 6A DB 77 10 24 DA 77  hj踳$趙
    00426010  00 00 00 00 A4 7F 33 77  ....?3w
    ......
    00426370  CF 90 32 76 0F DA 33 76  蠍2v?v
    00426378  00 00 00 00 59 58 F3 4F  ....YX驩
    00426380  0B 65 EE 4F 00 10 EF 4F  e頞.颫
    00426388  A8 12 EF 4F A6 F2 ED 4F  ?颫︱鞳
    00426390  00 00 00 00 00 00 00 00  ........

    一个完整的表,用Import.Reconstructor得到完整的表,保存备用。

    2.修复被壳转移的代码

    重新OD加载程序,重新对LoadLibraryA函数的代码下内存访问中断。F9运行:
    在第二次被中断在函数中时,Alt+M打开内存窗口,双击00401000段:
    00401000  MOV EAX,DWORD PTR SS:[ESP+4]
    00401004  MOV DWORD PTR DS:[440840],EAX
    00401009  CALL CryptCD_.00401080
    0040100E  CALL CryptCD_.00401320
    00401013  CALL CryptCD_.00403A20
    00401018  TEST EAX,EAX
    0040101A  JNZ SHORT CryptCD_.00401033
    0040101C  PUSH 5BCD98
    00401021  PUSH 6DE6CC
    00401026  CALL CryptCD_.00403560

    对0040101C  PUSH 5BCD98下内存访问中断,Shift+F9运行:

    003780F0  PUSHAD
    003780F1  PUSH 4
    003780F3  PUSH 3000
    003780F8  PUSH 5D58
    003780FD  PUSH 0
    003780FF  CALL DWORD PTR SS:[EBP+4]
    00378102  XCHG EAX,EDI
    00378103  CALL 003780E9
    00378108  LEA ESI,DWORD PTR SS:[EBP-5]
    0037810B  SUB ESI,0BAB
    00378111  PUSH ESI
    00378112  MOV EBX,101
    00378117  XOR BYTE PTR DS:[EDI],DL
    00378119  INC EDI
    0037811A  MOV EDX,DWORD PTR DS:[ESI]
    0037811C  ADD ESI,4
    0037811F  MOV BYTE PTR DS:[EDX],0E9
    00378122  MOV EAX,EDI
    00378124  SUB EAX,EDX
    00378126  SUB EAX,5
    00378129  MOV DWORD PTR DS:[EDX+1],EAX
    0037812C  MOV AL,BYTE PTR DS:[ESI]
    0037812E  INC ESI
    0037812F  MOVZX ECX,AL
    00378132  AND EAX,3
    00378135  SHR ECX,2
    00378138  REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
    0037813A  MOV ECX,EAX
    0037813C  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
    0037813E  MOV AL,BYTE PTR DS:[ESI]
    00378140  INC ESI
    00378141  ADD EDX,EAX
    00378143  MOV BYTE PTR DS:[EDI],0E9
    00378146  SUB EDX,EDI
    00378148  SUB EDX,5
    0037814B  MOV DWORD PTR DS:[EDI+1],EDX
    0037814E  ADD EDI,5
    00378151  DEC EBX
    00378152  JNZ SHORT 00378117
    00378154  POP EDI
    00378155  LEA ECX,DWORD PTR SS:[EBP+66]
    00378158  SUB ECX,EDI
    0037815A  REP STOS BYTE PTR ES:[EDI]
    0037815C  POPAD
    0037815D  RETN



    这段代码就是把程序的代码修改为调用到壳中转移的地址,分析这段代码

    0037811F  MOV BYTE PTR DS:[EDX],0E9
    修改[EDX]指向的地址40101C为JMP

    00378122  MOV EAX,EDI
    00378124  SUB EAX,EDX
    00378126  SUB EAX,5
    00378129  MOV DWORD PTR DS:[EDX+1],EAX

    计算跳转偏移,然后写入到程序中

    0037812C  MOV AL,BYTE PTR DS:[ESI]
    0037812E  INC ESI
    0037812F  MOVZX ECX,AL
    00378132  AND EAX,3
    00378135  SHR ECX,2
    00378138  REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
    0037813A  MOV ECX,EAX
    0037813C  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]

    到[ESI]指向的地址看看:

    0037753E  1C 10 40 00 05 68 C4 82  @.h膫
    00377546  42 00 05 21 10 40 00 05  B.!@.
    0037754E  68 B8 82 42 00 05 38 10  h競B.8
    00377556  40 00 05 68 18 82 42 00  @.h侭.
    0037755E  05 3D 10 40 00 05 68 08  =@.h
    00377566  82 42 00 05 53 10 40 00  侭.S@.
    0037756E  05 68 F0 81 42 00 05 58  h饋B.X
    00377576  10 40 00 05 68 E4 81 42  @.h鋪B
    0037757E  00 05 81 10 40 00 12 8D  .?@.

    这个地址中其实是一个表,表的组成是:
    1.)需要修改的程序地址 :1C 10 40 00
    2.)需要复制到壳申请临时空间的代码长度:05
    3.)需要转移的代码:68 C4 82 42 00
    4.)写入jump回程序中地址的偏移:05

    0037813E  MOV AL,BYTE PTR DS:[ESI]
    00378140  INC ESI
    00378141  ADD EDX,EAX
    00378143  MOV BYTE PTR DS:[EDI],0E9
    00378146  SUB EDX,EDI
    00378148  SUB EDX,5
    0037814B  MOV DWORD PTR DS:[EDI+1],EDX

    计算jump回到程序中的偏移,写入jump回的代码

    分析完了上面的流程和方法后,就可以利用这段代码把转移的代码写回到程序中:

    修改:
    003780F0  PUSHAD
    003780F1  PUSH 4
    003780F3  PUSH 3000
    003780F8  PUSH 5D58
    003780FD  PUSH 0
    003780FF  CALL DWORD PTR SS:[EBP+4]
    00378102  XCHG EAX,EDI
    00378103  CALL 003780E9
    00378108  LEA ESI,DWORD PTR SS:[EBP-5]
    0037810B  SUB ESI,0BAB
    00378111  PUSH ESI
    00378112  MOV EBX,101
    00378117  NOP
    00378118  NOP
    00378119  INC EDI
    0037811A  MOV EDX,DWORD PTR DS:[ESI]
    0037811C  ADD ESI,4
    0037811F  MOV EDI,EDX      //关键,把壳的地址替换为程序的地址
    00378121  NOP
    00378122  MOV EAX,EDI
    00378124  SUB EAX,EDX
    00378126  SUB EAX,5
    00378129  NOP
    0037812A  NOP
    0037812B  NOP
    0037812C  MOV AL,BYTE PTR DS:[ESI]
    0037812E  INC ESI
    0037812F  MOVZX ECX,AL
    00378132  AND EAX,3
    00378135  SHR ECX,2
    00378138  REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
    0037813A  MOV ECX,EAX
    0037813C  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
    0037813E  MOV AL,BYTE PTR DS:[ESI]
    00378140  INC ESI
    00378141  ADD EDX,EAX
    00378143  NOP
    00378144  NOP
    00378145  NOP
    00378146  SUB EDX,EDI
    00378148  SUB EDX,5
    0037814B  NOP
    0037814C  NOP
    0037814D  NOP
    0037814E  ADD EDI,5
    00378151  DEC EBX
    00378152  JNZ SHORT 00378117
    00378154  POP EDI
    00378155  LEA ECX,DWORD PTR SS:[EBP+66]
    00378158  SUB ECX,EDI
    0037815A  REP STOS BYTE PTR ES:[EDI]
    0037815C  POPAD
    0037815D  RETN

    修改完成后,F4到0037815D  RETN

    Alt+M打开内存窗口,在00401000的代码段下内存访问中断,Shift+F9运行程序:

    0041B9D4  CALL DWORD PTR DS:[426124]
    0041B9DA  XOR EDX,EDX
    0041B9DC  MOV DL,AH
    0041B9DE  MOV DWORD PTR DS:[441C04],EDX

    这是程序的伪OEP,在堆栈中检查:

    0012FFA8   0012FFB8  指针到下一个 SEH 记录
    0012FFAC   0041F270  SE 句柄
    0012FFB0   004263F0  CryptCD_.004263F0
    0012FFB4   FFFFFFFF
    0012FFB8   0012FFE0  指针到下一个 SEH 记录

    这个程序是VC++编译的,根据堆栈中的数据恢复代码:

    0041B9AE >PUSH EBP
    0041B9AF  MOV EBP,ESP
    0041B9B1  PUSH -1
    0041B9B3  PUSH CryptCD_.004263F0
    0041B9B8  PUSH CryptCD_.0041F270                   ;  SE handler installation
    0041B9BD  MOV EAX,DWORD PTR FS:[0]
    0041B9C3  PUSH EAX
    0041B9C4  MOV DWORD PTR FS:[0],ESP
    0041B9CB  SUB ESP,58
    0041B9CE  PUSH EBX
    0041B9CF  PUSH ESI
    0041B9D0  PUSH EDI
    0041B9D1  MOV DWORD PTR SS:[EBP-18],ESP

    用LordPE dump下程序,修改程序的OEP为0041B9AE,保存备用.

    3.还原IAT表

    用Import.Reconstructor加载保存的iat表,去掉增加新的区段的勾,然后在新的输入表信息的
    RVA 中填入原iat表的RVA 00026000 在OEP中填入0001B9AE 后,修复上面保存的dump程序.
    看似修复好了iat表,运行看看,程序不见了:( 看来还是有问题.有什么问题呢?

    用OD 加载原程序,直接运行,运行成功后来到imports段00426000
    再用OD加载修复后的dump程序,比较imports段和原来的有些什么不同,发现原imports表中多了些数据:

    00426390  00 00 00 00 00 00 00 00 9A 99 99 99 99 99 E9 3F  ........殭櫃櫃?
    004263A0  00 00 00 00 00 00 50 3F 00 00 80 3A 00 00 00 00  ......P?..
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-12-1 11:04
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    发表于 2006-6-23 20:12:02 | 显示全部楼层
    原帖由 繁华亦凄凉 于 2006-6-23 15:27 发表
    我很菜,想和大家学点东西,感谢有这么一个空间.
    我刚刚学脱壳不久,遇到了俩很难的壳.
    在网上找了很就,没有找到太好的解决办法(也许我太菜了)
    希望高人可以点动画来帮助我们刚刚接触脱壳的小菜鸟.
    一个 ...



    刚刚学脱壳,建议从简单的如:UPX,ASP开始~~
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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