cndml 发表于 2020-9-5 21:26

winlicense3.0.4 脱壳破解

wl3.0破解的帖子不多,今天闲来无事,写一点破解的体会,希望能起到抛砖引玉的效果,最先是在tuts看到一个求助帖,没人回复,试了一下,难度有点大,在别的帖子受到一些启发,遂开始破解历程,总起来说破解的思路、脚本的编写基本还是来自大牛lct的思路,因为一个软件无论多么nb,大的架构很难有翻天覆地的变化,知识总是要不断传承的。
原帖地址:https://forum.tuts4you.com/topic/42036-winlicense-3040-demo-hwid-bypass/?do=findComment&comment=203450
原文件就不上传了,国外网站访问只有几k的速度,不是一般个慢,把lct的回复贴上来

Hi,
have seen your post today by reading this topic....
https://forum.tuts4you.com/topic/42308-someone-can-help-me-unpack-themida-winlicense-v3000-3040/?tab=comments#comment-205628
...now I was just checking compare commands only on fly and you can still bypass HWID.Patch that 2 times after each NAG (HWID & Sorry).Just quick bypass method but also working.
004C9D0CCMP DWORD PTR DS:,ECX   ; x2
ECX=7AC7A65D
Stack DS:=17DA4FB6             ; make same = 17DA4FB6 = Sorry without license... MSG


Hi,
not sure whether or if I do update my script,Just using WIn 10 64 only at the moment and debug pretty less.
About the address of compare.I forgot that ASLR was enabled in that file.The RVA address is 139D0C (just add your base).Otherwise just use simple method I told before, find all compare commands "cmp ,r32" sequences and check whether commands are real (scroll up/down and see code itself) and set BPs on all.You can do this when you got the HWID nag so then just press pause.If you found all sequences and you did set all BPs then save them with BP manager plugin (optional you can do this).Just enable all BPs when you did bypass the NAG (pause / BP on called from / run / press button on NAG = Stop and now enable the compare BPs).In this case just do it twice stopping on same compare command and then make the compare just same (dwords can be diffrent on each check).Now the app should run as on the picture I made.
greetz

按照这个思路,搞定hwid没有问题,估计是demo版有所保留。一个网友的求破软件按照这个思路也可以破解hwid绑定,脱壳也没啥问题,log以及修复要用到下面的脚本,一个是我自己写的,一个是网上借用的。

bc
bpmc
bphwc
pause
pause
gpa "VirtualAlloc",   "kernel32.dll"
mov VirtualAlloc,      $RESULT
bp VirtualAlloc
start:
erun
cmp ,5000
jnz start
bc eip
//////////////////////////////
mov SP_FOUND,72c000
NO_SPECIAL_NEEDED2:
find SP_FOUND, #39??9C#// cmp ,r32
cmp $RESULT, 00
je SPECIAL_POINT_OUT_NEXT
mov SP_FOUND, $RESULT
cmp , 66, 01
inc SP_FOUND
je NO_SPECIAL_NEEDED2
dec SP_FOUND
gci SP_FOUND, SIZE
inc SP_FOUND
cmp $RESULT, 02
jne NO_SPECIAL_NEEDED2
dec SP_FOUND
//add SP_FOUND, 03
bp SP_FOUND
cmt SP_FOUND, "SPECIAL"
add SP_FOUND, 02
jmp NO_SPECIAL_NEEDED2
//////////////////////////////
SPECIAL_POINT_OUT_NEXT:
pause
pause
start1:
run
GOPI eip, 1, ADDR
mov msg1,$RESULT
GOPI eip, 1, DATA
mov msg2,$RESULT
GOPI eip, 2, DATA
mov msg3,$RESULT
eval "{eip}[{msg1}]{msg2}   {msg3}"
wrta "123456.txt", $RESULT
goto start1

end:

///////////////////////////////////////////////////////////////////////
//假设当前你已停在OEP附近,填完初始化地址即可开始跑脚本
//软件断点必须是占1个字节的,不能占2个字节以上
//initialization start
mov FixStartAddr,0x140001000            //初始化,前2个填text区段起始和末尾地址,后2个填wl壳区段起始和末尾地址   
mov FixEndAddr,0x140002000
mov wlStartAddr,0x140008000
mov wlEndAddr,0x1406ac000
//initialization end   
//setfreezestack 1                     //关闭GUI更新,防止dbg崩溃。
//LogDisable
//guiupdatedisable

alloc 0x20000                        //申请内存当做堆栈,以及给替换代码使用以防崩溃
mov cxpvalue,$RESULT+0x5000         
mov cbpvalue,$RESULT+0x10000         //固定cbp,csp
mov cspvalue,$RESULT+0x10000-0x100
BPHWC                              //删除所有断点
BC   
BPMC
mov temp,FixStartAddr
mov NewIATAddr,wlEndAddr-0x2000      //往壳区段写入新IAT
mov SpecialAddr,wlEndAddr-0x3000   //往壳区段写入某些特殊的jmp
mov Call_Addr,0
mov Call_data,0
mov Call_jmpAddr,0

LOOP_Fix:
call FindCall(ff15)                        //寻找可能的call_section
cmp $RESULT,0                        //为0则修复完毕
je Loop_fix(2)
mov cax,cxpvalue                     //给替换代码使用以防崩溃(还解决了一些莫名其妙的异常崩溃问题,建议以后写脚本都留着)
mov cbx,cxpvalue
mov ccx,cxpvalue
mov cdx,cxpvalue
mov csi,cxpvalue
mov cdi,cxpvalue
mov cbp,cbpvalue                     //固定cbp,csp,以防某些情况下的堆栈崩溃
mov csp,cspvalue
call FixCallData                     //开始修复CALL_Section和IAT

jmp LOOP_Fix



FindCall(ff15):
find temp,FF15??????00,FixEndAddr-FixStartAddr
cmp $RESULT,0
je End1
mov Call_Addr,$RESULT
mov temp,Call_Addr+1
mov Call_data,4:
mov Call_jmpAddr,Call_Addr+Call_data+6
//mov Call_jmpAddr,Call_Addr+Call_data+5
mov Call_index,
cmp Call_index,wlStartAddr
jle FindCall(ff15)
cmp Call_index,wlEndAddr
jge FindCall(ff15)
ret

FindCall(ff25):
find temp,FF25??????00,FixEndAddr-FixStartAddr
cmp $RESULT,0
je End1
mov Call_Addr,$RESULT
mov temp,Call_Addr+1
mov Call_data,4:
mov Call_jmpAddr,Call_Addr+Call_data+6
//mov Call_jmpAddr,Call_Addr+Call_data+5
mov Call_index,
cmp Call_index,wlStartAddr
jle FindCall(ff25)
cmp Call_index,wlEndAddr
jge FindCall(ff25)
ret
End1:
ret
End2:
setfreezestack 0                     //解锁堆栈、GUI、日志记录
guiupdateenable 1
LogEnable
ret

FixCallData:
mov cip,Call_Addr                  //将CIP设置在call_section
sti                                  //第一处“奇妙”
mov ,0                        //这里必须要赋0,否则会影响后续call和jmp的识别
add csp,4
mov cip,Call_Addr
jmp Runinto

Runinto:
ticnd (mod.isexport(cax)==1||(CIP>wlEndAddr)||(CIP<wlStartAddr),0x100   //寻找xor eax,ebx/ecx/edx/.......
cmp CIP,wlStartAddr                  //判断找到的代码是不是壳区段中的。不是则说明它是替换代码
jle Special2
cmp CIP,wlEndAddr
jge Special2
//cmp 1:,0x31e8                     //判断找到的代码并跳到相应的脚本命令
//je xor_index
//cmp 1:,0x31d0                     //判断找到的代码并跳到相应的脚本命令
//je xor_index
//cmp 1:,0x31f0                     //判断找到的代码并跳到相应的脚本命令
//je xor_index
//cmp 1:,0x31f8                     //判断找到的代码并跳到相应的脚本命令
//je xor_index
//cmp 1:,0x31d8                     //判断找到的代码并跳到相应的脚本命令
//je xor_index
//cmp 1:,0x31c8                     //判断找到的代码并跳到相应的脚本命令
//je xor_index
//sti
jmp xor_index

xor_index:
sti                                 
mov APIAddr,cax                  //取得API地址
jmp Start_FixData                   //跳去修复数据


Special2:

BPHWC
ret

Start_FixData:
Call_IAT:
//mov ,APIAddr             //向IAT中写入API地址
cmp APIAddr,0
je Special2
mov ,APIAddr
NewIATAddr+=4
ret

Loop_fix(2):
call FindCall(ff25)                        //寻找可能的Jmp_section
cmp $RESULT,0                        //为0则修复完毕
je End2
mov cax,cxpvalue                     //给替换代码使用以防崩溃(还解决了一些莫名其妙的异常崩溃问题,建议以后写脚本都留着)
mov cbx,cxpvalue
mov ccx,cxpvalue
mov cdx,cxpvalue
mov csi,cxpvalue
mov cdi,cxpvalue
mov cbp,cbpvalue                     //固定cbp,csp,以防某些情况下的堆栈崩溃
mov csp,cspvalue
call FixCallData                     //开始修复Jmp_Section和IAT
jmp Loop_fix(2)


程序名:CCFMaster_1.6Pro.exe程序太大没法发上来

破解hwid程序能够运行起来,程序是qt5打包的,附在附加数据里,解包正常,不过可惜还有网络验证,不清楚如何才能更改脚本跳过网络验证


脱壳修复因该是没有问题的,qt5附加数据解包对比后,也是正确的,但是脱壳程序运行不起来,提示如下错误



网上搜索半天,没整出个所以然来,只好放弃,有了解的朋友可以指点一二!

董督秀 发表于 2020-9-5 21:33

wl3.0.4用lcf的脚本搞不定,提示发现调试器,不知道如何解决?很少上tust to you论坛,不知道可否咨询lcf-at本人,关于wl3.0.4的脱壳思路?:(eew

Aska 发表于 2020-9-5 21:44

感谢大佬分享,虽然看不懂{:1_909:}

董督秀 发表于 2020-9-5 21:46

csdn上确实有3.0.4的修复脚本,是基于x64dbg的。

boywhocools 发表于 2020-9-6 08:54

winlicense加密的好像不多

kemchi 发表于 2020-9-6 08:59

本帖最后由 kemchi 于 2020-9-6 09:01 编辑

楼主有3.0.4的破解版吗,论坛上面的都是2的。

jccforever 发表于 2020-9-7 21:13

楼主 这个软件可有链接??
页: [1]
查看完整版本: winlicense3.0.4 脱壳破解