欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

Zprotect1.4-1.6 patch KEY脱壳

程序员文章站 2022-03-31 10:10:14
对于ZProtect 1.4.x版本的系列软件,只要有其一个可用的机器码和key就可实现完美脱壳。   对于ZProtect 目前版本(ZP1.60)加壳的所有软件,只要有其一个...
对于ZProtect 1.4.x版本的系列软件,只要有其一个可用的机器码和key就可实现完美脱壳。

 

对于ZProtect 目前版本(ZP1.60)加壳的所有软件,只要有其一个可用的机器码和key就可实现完美脱壳。

 

假设已有一个可用的机器码和KEY:

机器码:AAAA-BBBB-CCCC-DDDD

序列号:B131FA844E0E9A7F32810DD67B9C4DC086EB

 

脚本流程:

1,寻找OEP断点。这个原理很简单,所谓的ESP平衡定律就是了。

2,对机器码进行补丁。zprotect用DeviceIoControl函数获取机器码相关,只要对该函数设置断点即可。当提示需输入机器号的前8位时,本例中,输入AAAABBBB,后8位即为CCCCDDDD。

3,修复IAT。本版本中IAT的起始和结束部分仍然需要手动填入。

4,用loadpe和IMR修复即可。

 

脚本内容:

 

BC

BPMC

BPHWC

call VARSINIT

//pause

sti

FIND_OEP:

mov EipForOep_1, eip

mov EipForOep_1, [EipForOep_1]

and EipForOep_1, 0ff

cmp EipForOep_1, 60

jne OEP_NEXT

sti

mov bpforoep, esp

jmp HWIDPatchStart

OEP_NEXT:

sto

jmp FIND_OEP

HWIDPatchStart:

////////////////////

HWID_PATCH:

bphws DeviceIoControl, "x"

bp DeviceIoControl

bphws VirtualAlloc, "x"

bp VirtualAlloc

esto

////////////////////

HWID_PATCH_CHECK_NEXT:

cmp eip, VirtualAlloc

jne HWID_PATCH_2

bphwc

bc

mov A_SIZE, [esp+08]

rtr

mov A_ADDRESS, eax

bphws DeviceIoControl, "x"

bp DeviceIoControl

bphws VirtualAlloc, "x"

bp VirtualAlloc

HWID_PATCH_CHECK_NEXT_ZHW: //zenghw add

esto

////////////////////

FIND_STRING:

mov tempdata,[esp]//zenghw add

cmp tempdata,77DA9559

je HWID_PATCH_CHECK_NEXT_ZHW

cmp eip, DeviceIoControl

je HWID_PATCH_2

find A_ADDRESS, #0FB?542410E9#

cmp $RESULT, 00

je HWID_PATCH_CHECK_NEXT

mov A_ADDRESS, $RESULT

inc A_ADDRESS

mov A_ADDRESS_BAK, $RESULT

mov dll, 01

add A_ADDRESS, 04

gci A_ADDRESS, DESTINATION

cmp $RESULT, 00

sub A_ADDRESS, 04

je FIND_STRING

mov ABC, $RESULT

cmp [ABC+03], 1124, 02 

jne FIND_STRING

add ABC, 05

cmp [ABC], E8, 01

jne FIND_STRING_B

mov call, 01

////////////////////

FIND_STRING_B:

gci ABC, DESTINATION

cmp $RESULT, 00

sub ABC, 05

je FIND_STRING

mov ABC, $RESULT

cmp call, 01

je FIND_STRING_C

cmp [ABC], 30, 01

jne FIND_STRING

////////////////////

FIND_STRING_C:

mov A_ADDRESS, A_ADDRESS_BAK

jmp HWID_PATCH_2

jmp HWID_PATCH

////////////////////

HWID_PATCH_2:

bphwc

bc

cmp dll, 01

jne HWID_PATCH_2_A

gmemi A_ADDRESS, MEMORYBASE

mov VMBASE, $RESULT

mov $RESULT, A_ADDRESS

jmp found

////////////////////

HWID_PATCH_2_A:

mov EXTRA, [esp]

gmemi EXTRA, MEMORYBASE

mov EXTRA, $RESULT

rtu

gmemi eip, MEMORYBASE

cmp EXTRA, $RESULT

jne VM

gmemi eip, MEMORYBASE

mov EXTRA_2, $RESULT

cmp [EXTRA_2], 5A4D, 02

jne VM

rtr

mov baceip, eip

////////////////////

SELFTEST:

sti

cmp eip, baceip

je SELFTEST

////////////////////

VM:

gmemi eip, MEMORYBASE

mov VMBASE, $RESULT

////////////////////

SEARCH:

find VMBASE, #0FB?542410E9#

cmp $RESULT, 00

jne found

find A_ADDRESS, #0FB?542410E9#

cmp $RESULT, 00

je SEARCH_3

////////////////////

SEARCH_2:

mov A_ADDRESS, $RESULT

gmemi A_ADDRESS, MEMORYBASE

mov VMBASE, $RESULT

mov $RESULT, A_ADDRESS

jmp found

////////////////////

SEARCH_3:

findmem  #0FB?542410E9#, CODESECTION

cmp $RESULT, 00

jne SEARCH_3_A

pause

pause

pause

////////////////////

SEARCH_3_A:

mov A_ADDRESS, $RESULT

gmemi A_ADDRESS, MEMORYBASE

mov VMBASE, $RESULT

mov $RESULT, A_ADDRESS

jmp found

pause

pause

////////////////////

found:

mov FOUND, $RESULT

add PLUS_1, FOUND

sub PLUS_1, VMBASE

mov PLUS_1, PLUS_1

log PLUS_1

bp FOUND

bphws FOUND, "x"

esto

mov ID,  [esp+10]

mov ID2, [esp+14]

alloc 1000

mov mem, $RESULT

mov baceip, eip

////////////////////

Ask3:

ask "输入可用机器码的前8个字节,如:AAAABBBB"

cmp $RESULT,0

je Ask3

cmp $RESULT, -1

je Ask3

mov ID_1, $RESULT

////////////////////

Ask4:

ask "输入可用机器码的后8个字节,如:CCCCDDDD"

cmp $RESULT,0

je Ask4

cmp $RESULT, -1

je Ask4

mov ID_2, $RESULT

mov temp2,eax

mov test, ##+"0000-0000-0000-0000"

mov [mem], test

mov eax, ID_1

shr eax, 10

mov I1, ax

mov eax, ID_1

mov I2, ax

itoa I1, 16.

mov I1, $RESULT

len I1

cmp $RESULT, 04

je CW_GO

////////////////////

AB1:

cmp $RESULT, 03

jne AB2

eval "0{I1}"

mov I1, $RESULT

jmp CW_GO

////////////////////

AB2:

cmp $RESULT, 02

jne AB3

eval "00{I1}"

mov I1, $RESULT

jmp CW_GO

////////////////////

AB3:

cmp $RESULT, 01

jne AB4

eval "000{I1}"

mov I1, $RESULT

jmp CW_GO

////////////////////

AB4:

cmp $RESULT, 00

jne AB5

mov I1, "0000"

jmp CW_GO

////////////////////

AB5:

pause

pause

pause

////////////////////

CW_GO:

itoa I2, 16.

mov I2, $RESULT

len I2

cmp $RESULT, 04

je CW_GO_2

////////////////////

AB1A:

cmp $RESULT, 03

jne AB2A

eval "0{I2}"

mov I2, $RESULT

jmp CW_GO_2

////////////////////

AB2A:

cmp $RESULT, 02

jne AB3A

eval "00{I2}"

mov I2, $RESULT

jmp CW_GO_2

////////////////////

AB3A:

cmp $RESULT, 01

jne AB4

eval "000{I2}"

mov I2, $RESULT

jmp CW_GO_2

////////////////////

AB4A:

cmp $RESULT, 00

jne AB5A

mov I2, "0000"

jmp CW_GO_2

////////////////////

AB5A:

pause

pause

pause

////////////////////

CW_GO_2:

eval "{I1}-{I2}"

mov test, ##+$RESULT

mov [mem], test

mov eax, ID_2

shr eax, 10

mov I3, ax

mov eax, ID_2

mov I4, ax

itoa I3, 16.

mov I3, $RESULT

len I3

cmp $RESULT, 04

je CW_GO_3

////////////////////

AB1B:

cmp $RESULT, 03

jne AB2B

eval "0{I3}"

mov I3, $RESULT

jmp CW_GO_3

////////////////////

AB2B:

cmp $RESULT, 02

jne AB3B

eval "00{I3}"

mov I3, $RESULT

jmp CW_GO_3

////////////////////

AB3B:

cmp $RESULT, 01

jne AB4B

eval "000{I3}"

mov I3, $RESULT

jmp CW_GO_3

////////////////////

AB4B:

cmp $RESULT, 00

jne AB5B

mov I3, "0000"

jmp CW_GO_3

////////////////////

AB5B:

pause

pause

pause

////////////////////

CW_GO_3:

itoa I4, 16.

mov I4, $RESULT

len I4

cmp $RESULT, 04

je CW_GO_4

////////////////////

AB1C:

cmp $RESULT, 03

jne AB2C

eval "0{I4}"

mov I4, $RESULT

jmp CW_GO_4

////////////////////

AB2C:

cmp $RESULT, 02

jne AB3C

eval "00{I4}"

mov I4, $RESULT

jmp CW_GO_4

////////////////////

AB3C:

cmp $RESULT, 01

jne AB4C

eval "000{I4}"

mov I4, $RESULT

jmp CW_GO_4

////////////////////

AB4C:

cmp $RESULT, 00

jne AB5C

mov I4, "0000"

jmp CW_GO_4

////////////////////

AB5C:

pause

pause

pause

////////////////////

CW_GO_4:

eval "{I3}-{I4}"

mov test, ##+$RESULT

mov [mem+0A], test

////////////////////

BIG_LOOP:

mov CALC, mem

////////////////////

BIG_LOOP_2:

cmp [mem], 61, 01

je 20

cmp [mem], 62, 01

je 20

cmp [mem], 63, 01

je 20

cmp [mem], 64, 01

je 20

cmp [mem], 65, 01

je 20

cmp [mem], 66, 01

je 20

////////////////////

BIG_LOOP_3:

inc mem

inc counta

cmp counta, 13

je FERTIG

jmp BIG_LOOP_2

////////////////////

20:

sub [mem], 20

jmp BIG_LOOP_3

////////////////////

FERTIG:

mov mem, CALC

mov counta, 00

cmp SECOND_LOOP, 01

je END_SECOND_LOOP

readstr [mem], 13

mov STRING, $RESULT

str STRING

mov STRING, STRING

mov eax, temp2

fill mem, 100, 00

mov temp2, eax

mov test, ##+"0000-0000-0000-0000"

mov [mem], test

mov eax, [esp+10]

mov I1, ax

shr eax, 10

mov I2, ax

mov eax, [esp+14]

mov I3, ax

shr eax, 10

mov I4, ax

itoa I1, 16.

mov I1, $RESULT

len I1

cmp $RESULT, 04

je CW_GO_5

////////////////////

AB1D:

cmp $RESULT, 03

jne AB2D

eval "0{I1}"

mov I1, $RESULT

jmp CW_GO_5

////////////////////

AB2D:

cmp $RESULT, 02

jne AB3D

eval "00{I1}"

mov I1, $RESULT

jmp CW_GO_5

////////////////////

AB3D:

cmp $RESULT, 01

jne AB4D

eval "000{I4}"

mov I1, $RESULT

jmp CW_GO_5

////////////////////

AB4D:

cmp $RESULT, 00

jne AB5D

mov I1, "0000"

jmp CW_GO_5

////////////////////

AB5D:

pause

pause

pause

////////////////////

CW_GO_5:

itoa I2, 16.

mov I2, $RESULT

len I2

cmp $RESULT, 04

je CW_GO_6

////////////////////

AB1E:

cmp $RESULT, 03

jne AB2E

eval "0{I2}"

mov I2, $RESULT

jmp CW_GO_6

////////////////////

AB2E:

cmp $RESULT, 02

jne AB3E

eval "00{I2}"

mov I2, $RESULT

jmp CW_GO_6

////////////////////

AB3E:

cmp $RESULT, 01

jne AB4E

eval "000{I2}"

mov I2, $RESULT

jmp CW_GO_6

////////////////////

AB4E:

cmp $RESULT, 00

jne AB5E

mov I2, "0000"

jmp CW_GO_6

////////////////////

AB5E:

pause

pause

pause

////////////////////

CW_GO_6:

eval "{I1}-{I2}"

mov test, ##+$RESULT

mov [mem], test

itoa I3, 16.

mov I3, $RESULT

len I3

cmp $RESULT, 04

je CW_GO_7

////////////////////

AB1F:

cmp $RESULT, 03

jne AB2F

eval "0{I3}"

mov I3, $RESULT

jmp CW_GO_7

////////////////////

AB2F:

cmp $RESULT, 02

jne AB3F

eval "00{I3}"

mov I3, $RESULT

jmp CW_GO_7

////////////////////

AB3F:

cmp $RESULT, 01

jne AB4F

eval "000{I3}"

mov I3, $RESULT

jmp CW_GO_7

////////////////////

AB4F:

cmp $RESULT, 00

jne AB5F

mov I3, "0000"

jmp CW_GO_7

////////////////////

AB5F:

pause

pause

pause

////////////////////

CW_GO_7:

itoa I4, 16.

mov I4, $RESULT

len I4

cmp $RESULT, 04

je CW_GO_8

////////////////////

AB1G:

cmp $RESULT, 03

jne AB2G

eval "0{I4}"

mov I4, $RESULT

jmp CW_GO_8

////////////////////

AB2G:

cmp $RESULT, 02

jne AB3G

eval "00{I4}"

mov I4, $RESULT

jmp CW_GO_8

////////////////////

AB3G:

cmp $RESULT, 01

jne AB4G

eval "000{I4}"

mov I4, $RESULT

jmp CW_GO_8

////////////////////

AB4G:

cmp $RESULT, 00

jne AB5G

mov I4, "0000"

jmp CW_GO_8

////////////////////

AB5G:

pause

pause

pause

////////////////////

CW_GO_8:

eval "{I3}-{I4}"

mov test, ##+$RESULT

mov [mem+0A], test

mov SECOND_LOOP, 01

jmp BIG_LOOP

////////////////////

END_SECOND_LOOP:

readstr [mem], 13

mov STRING_2, $RESULT

str STRING_2

mov STRING_2, STRING_2

mov eax, temp2

fill mem, 100, 00

mov SECOND_LOOP, 00

mov [mem], ID_1

mov [mem+04], ID_2

mov [mem+12], [mem], 2

mov [mem+10], [mem+2], 2

mov [mem+16], [mem+4], 2

mov [mem+14], [mem+6], 2

mov ID_1, [mem+10] 

mov ID_2,[mem+14] 

fill mem, 100, 00

bc FOUND

bphwc

readstr [eip], 0A

mov place, $RESULT

buf place

mov test,eip

add test, 05

gci test, DESTINATION

mov ort, $RESULT

eval "jmp {mem}"

asm eip, $RESULT

mov [mem], #81FAAAAAAAAA751A81F9AAAAAAAA7512BABBBBBBBBB9CCCCCCCC89542410894C24149090#

cmp $RESULT, 01

jmp END_SECOND_LOOP_2

////////////////////

END_SECOND_LOOP_2:

add mem, 22

mov [mem], place

sub mem, 22

mov [mem+02],ID

mov [mem+0A],ID2

mov [mem+11],ID_1

mov [mem+16],ID_2

eval "jmp {ort}"

asm mem+27, $RESULT

add PLUS_2, ort

sub PLUS_2, VMBASE

mov PLUS_2, PLUS_2

readstr [mem], 028

 

jmp FULL_END

esto

pause

pause

////////////////////

VARSINIT:

/////////////////ZENGHW ADD ////////

var tempdata 

var vmaddr

var apiaddr

var IAT_Start

var IAT_End

var vmapiaddr

var EipForOep_1

var EipForOep_2

var EipForOep_3

var oep

var bpforoep

var tmp1

var tmp2

var EXTRA_2

var EXTRA

var mem

var SECOND_LOOP

var STRING_2

var counta

var test

var STRING

var CALC

var I1

var I2

var I3

var I4

var PLUS_1

var PLUS_2

var CHECK

var TEMP_CHECK

var CODESECTION

var CODESECTION_SIZE

var dll

var call

////////////////////

gpa "DeviceIoControl", "kernel32.dll"

mov DeviceIoControl,    $RESULT

gpa "VirtualAlloc",    "kernel32.dll"

mov VirtualAlloc,       $RESULT

gpa "VirtualProtect",  "kernel32.dll"

mov VirtualProtect,     $RESULT

gpa "MapViewOfFile",    "kernel32.dll"

mov MapViewOfFile,      $RESULT

ret

////////////////////

FULL_END:

cmp TEMP_CHECK, 0

je FULL_END_2

free TEMP_CHECK

////////////////////

FULL_END_2:

//pause

//ret

//start:

findoep:

BPHWCALL

BPHWS bpforoep, "r"

run

mov EipForOep_2, eip

mov EipForOep_2, [EipForOep_2]

and EipForOep_2, 0ff

cmp EipForOep_2, E8

je findoep2

sto

sto

mov oep, eip

pause  //此处暂停后,可先查看IAT START和IAT END,然后修改fixiat里面的对应内容

msg "此处暂停后,可先查看IAT的起始和终止地址,然后修改fixiat里面对应的IAT_Start和IAT_Start!"

jmp fixiat

findoep2:

//msg "修复后,请手动查找OEP!"

sti

sto

sto

sto

sto

sto

mov oep, eip

fixiat:

mov IAT_Start, 0040306C  ////////////////////////////////////////

mov IAT_End, 00403098  ////////////////////////////////////////

fix:

mov eip, [IAT_Start]

mov EipForOep_3, eip

mov EipForOep_3, [EipForOep_3]

and EipForOep_3, 0ff

cmp EipForOep_3, 68

jne skipfix2

sto

sto

sto

sto

sto

sti

mov tmp1, eip

find eip, #7C#

cmp $RESULT, 0

je F2

mov tmp2, $RESULT

mov [tmp2], #EB#

mov eip, tmp1

F2:

run

sto www.2cto.com

cmp eip, 07000000

ja fix2

mov vmapiaddr, eip

sub vmapiaddr, vmaddr

add vmapiaddr, kernel32base

mov [IAT_Start], vmapiaddr

add IAT_Start,4

cmp IAT_Start, IAT_End

ja end

cmp [IAT_Start], 0

je skipfix

jmp fix

fix2:

mov eip, [IAT_Start]

mov EipForOep_3, eip

mov EipForOep_3, [EipForOep_3]

and EipForOep_3, 0ff

cmp EipForOep_3, 68

jne skipfix2

sto

sto

sto

sto

sto

sti

mov tmp1, eip

find eip, #7C#

cmp $RESULT, 0

je F3

mov tmp2, $RESULT

mov [tmp2], #EB#

mov eip, tmp1

F3:

run

sto

mov apiaddr, eip

mov [IAT_Start], apiaddr

add IAT_Start,4

cmp IAT_Start, IAT_End

ja end

cmp [IAT_Start], 0

je skipfix

jmp fix

skipfix:

add IAT_Start,4

cmp [IAT_Start], 0

je skipfix

jmp fix

skipfix2:

add IAT_Start,4

cmp IAT_Start, IAT_End

ja end

jmp fix

error:

msg "Fix IAT wrong!"

ret

end:

BPHWCALL

mov eip, oep

AN eip

ret