此文只作为研究和学习使用,脱壳部分带过
研究版本6.8.0.2365 可能记错了研究出来有一段时间了。
73D34223 mfc42.#1636_CString::AssignCopy         8BFF           mov     edi, edi
73D34225                                         56             push    esi
73D34226                                         57             push    edi
73D34227                                         8B7C24 0C      mov     edi, dword ptr ss:[esp+C]
73D3422B                                         57             push    edi
73D3422C                                         8BF1           mov     esi, ecx
73D3422E                                         E8 24000000    call    mfc42.#1584_CString::AllocBefore>
73D34233                                         57             push    edi
73D34234                                         FF7424 14      push    dword ptr ss:[esp+14]
73D34238                                         FF36           push    dword ptr ds:[esi]
73D3423A                                         E8 BFE4FFFF    call    <jmp.&msvcrt.memcpy>
73D3423F                                         8B06           mov     eax, dword ptr ds:[esi]
73D34241                                         8978 F8        mov     dword ptr ds:[eax-8], edi
73D34244                                         8B06           mov     eax, dword ptr ds:[esi]
73D34246                                         83C4 0C        add     esp, 0C
73D34249                                         C60407 00      mov     byte ptr ds:[edi+eax], 0
73D3424D                                         5F             pop     edi
73D3424E                                         5E             pop     esi
73D3424F                                         C2 0800        retn    8
所有的版本这里找到脚本拷贝地址
73D3423F    8B06            mov     eax, dword ptr ds:[esi]
条件为[eax]==0x206d6944 || [eax]==0x206d6964
当读取脚本Dim和dim 时断下来
可以逐步跟踪找到脚本代码.
过程:

程序脱壳以后,载入od,在73D3423F下断点条件是当读取脚本Dim和dim声明变量的时候断下。
停下来以后alt+f9返回到用户代码
004264B9      E8 1C21FFFF    call    <jmp.&mfc42.#860_CString::operator=>
004264BE      68 DC0B4800    push    脱壳可运.00480BDC
004264C3      8D4D BC        lea     ecx, dword ptr ss:[ebp-44]
004264C6      E8 0F21FFFF    call    <jmp.&mfc42.#860_CString::operator=>
004264CB      8B45 C0        mov     eax, dword ptr ss:[ebp-40]
004264CE      8B40 F8        mov     eax, dword ptr ds:[eax-8]
004264D1      8D4C07 01      lea     ecx, dword ptr ds:[edi+eax+1]
004264D5      8B46 14        mov     eax, dword ptr ds:[esi+14]
004264D8      8B7E 0C        mov     edi, dword ptr ds:[esi+C]
单步走.4264c6这里还会进来一次。alt+f9返回。
到4264d5 d ecx,就看到脚本缓冲区了。全部抓出来保存。待后修复。
我这里的脚本片段:
00F38093       44 69 6D 20 66 69 72 73 74 72 75       Dim firstru
00F380A3  6E 00 52 75 6E 4E 46 00 68 77 6E 64 3D 57 69 6E  n.RunNF.hwnd=Win
00F380B3  64 6F 77 2E 46 69 6E 64 28 22 4E 6F 74 65 70 61  dow.Find("Notepa
00F380C3  64 22 2C 30 29 00 68 77 6E 64 20 3D 20 30 00 52  d",0).hwnd = 0.R
00F380D3  75 6E 41 70 70 28 22 6E 6F 74 65 70 61 64 2E 65  unApp("notepad.e
00F380E3  78 65 22 29 00 35 30 30 30 00 31 30 30 2C 32 30  xe").5000.100,20
00F380F3  30 20 20 2F 2F 62 75 74 74 6F 6E 00 31 00 35 30  0  //button.1.50
00F38103  30 30 00 31 30 30 2C 32 30 30 20 2F 2F 61 67 72  00.100,200 //agr
00F38113  65 65 00 37 34 2C 31 00 36 35 2C 31 00 36 38 2C  ee.74,1.65,1.68,
00F38123  31 00 36 39 2C 31 00 37 37 2C 31 00 36 35 2C 31  1.69,1.77,1.65,1
00F38133  00 37 33 2C 31 00 37 36 2C 31 00 39 2C 31 20 20  .73,1.76,1.9,1
00F38143  2F 2F 74 61 62 00 38 37 2C 31 00 36 35 2C 31 00  //tab.87,1.65,1.


接下来找操作码地址。
抓出来脚本以后。f9让程序正常运行。
下断 hr ZwProtectVirtualMemory 
出现界面以后。按指定的热键激活脚本。
连续断下。每次按alt+f9
看到类似如下代码返回处
0043D4BE                       E8 7D92FEFF    call    脱壳可运.00426740
0043D4C3                       83C4 08        add     esp, 8
0043D4C6                       C745 D0 010000>mov     dword ptr ss:[ebp-30], 1
0043D4CD                       E8 3EBBFEFF    call    脱壳可运.00429010
0043D4D2                       8BC8           mov     ecx, eax
0043D4D4                       E8 07BCFEFF    call    脱壳可运.004290E0
0043D4D9                       8B4B 04        mov     ecx, dword ptr ds:[ebx+4]
0043D4DC                       8B040E         mov     eax, dword ptr ds:[esi+ecx]
0043D4DF                       8D3C0E         lea     edi, dword ptr ds:[esi+ecx]



单步到
0043D4DC                       8B040E         mov     eax, dword ptr ds:[esi+ecx]

d ecx为指令缓冲区.
00F2D784  4C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  L...............
00F2D794  00 00 00 00 00 00 00 00 D4 86 E0 73 50 45 AD 00  ........PE?
00F2D7A4  34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  4...............
00F2D7B4  00 00 00 00 00 00 00 00 D4 86 E0 73 00 45 AD 00  .........E?
00F2D7C4  48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  H...............
00F2D7D4  00 00 00 00 00 00 00 00 D4 86 E0 73 80 42 AD 00  ........B?
00F2D7E4  36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  6...............
00F2D7F4  00 00 00 00 00 00 00 00 D4 86 E0 73 40 46 AD 00  ........@F?
00F2D804  47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  G...............
00F2D814  00 00 00 00 00 00 00 00 D4 86 E0 73 F0 45 AD 00  ........?
00F2D824  30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  0...............
00F2D834  00 00 00 00 00 00 00 00 D4 86 E0 73 A0 45 AD 00  ........?
00F2D844  21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  !...............
00F2D854  00 00 00 00 00 00 00 00 D4 86 E0 73 30 47 AD 00  ........0G?
00F2D864  09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00F2D874  00 00 00 00 00 00 00 00 D4 86 E0 73 E0 46 AD 00  ........?
00F2D884  30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  0...............
00F2D894  00 00 00 00 00 00 00 00 D4 86 E0 73 90 46 AD 00  ........?
00F2D8A4  21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  !...............

每条指令信息长度为0x20
对应的指令表
脚本对应
44 69 6D 20 66 69 72 73 74 72 75 6E 00 
Dim firstrun.
最后的00标识一个被加密的指令.要对应如上的指令表查找
第一个4c指令对应脚本空格,脚本中第一个00对应指令表里第二个指令34,以此类推。部分脚本破译
 Dim firstrun
Sub RunNF
Plugin hwnd=Window.Find("Notepad",0)
If hwnd = 0
VBSCall RunApp("notepad.exe")
Delay 5000
MoveTo 100,200  //button
LeftClick 1
Delay 5000
MoveTo 100,200 //agree
KeyPressS 74,1
KeyPressS 65,1
KeyPressS 68,1
KeyPressS 69,1
KeyPressS 77,1

以下是我定义的部分操作码和对应的脚本符号
code0=00
codename0=KeyPress
code1=06
codename1=KeyPressS
code2=03
codename2=KeyPressH
code3=01
codename3=KeyDown
code4=02
codename4=KeyUp
code5=09
codename5=LeftClick
code6=21
codename6=MoveTo
code7=22
codename7=MoveR
code8=23
codename8=MouseWheel
code9=29
codename9=RestoreMousePos
code10=2A
codename10=LockMouse
code11=2B
codename11=UnlockMouse
code12=2E
codename12=WaitClick
code13=2C
codename13=WaitKey
code14=2D
codename14=GetLastKey
code15=2F
codename15=GetLastClick
code16=37
codename16=IfColor
code17=3A
codename17=EndIf
code18=3C
codename18=For
code19=3E
codename19=EndFor
code20=36
codename20=If
code21=3F
codename21=Goto
code22=40
codename22=Gosub
code23=35
codename23=Rem
code24=34
codename24=Sub
code25=41
codename25=Return
code26=30
codename26=Delay
code27=33
codename27=SayString
code28=31
codename28=MessageBox
code29=49
codename29=UserVar
code30=46
codename30=VBS
code31=4A
;Plugin
codename31= 
code32=4C
;//
codename32= 
code33=39
codename33=Elseif
code34=42
codename34=EndScript
code35=48
codename35=Plugin
code36=3B
codename36=While
code37=38
codename37=Else
还有很多没有时间研究。有兴趣的朋友继续深入吧。
而且精灵还要靠这个挣钱。写到这里吧