[原创]对某外挂的再次破解
文章作者:jacky信息来源:邪恶八进制信息安全团队([url=http://www.eviloctal.com/]www.eviloctal.com[/url])
事先说明下,我不是跟风,只是玩了几天游戏,所以才有此文。写的很粗糙,没有技术含量,只为求证,解惑。
第一步:脱壳
首先,PEID查壳:
Themida/WinLicense V1.8.X-V1.9.X Other -> Oreans Technologies * Sign.By.fly * 20080131 *
我这里用一个非常好工具直接脱之。
好了,脱壳完毕。
PEID再查:
Borland Delphi 6.0 - 7.0
这样第一步就完成了。
第二步:找关键代码
用DeDeDark找登陆事件。
打开DD,处理完毕。点过程,找到模块:TFormlogin,并在旁边事件中,找到btnCheckldClick
复制地址004C14E0,到此关键代码段就找到了。
第三步:破解
用OD载入,CTRL+G 到004C14E0地址,下断。
F9运行,填入错误验证。
F8步过。
一直到:
004C1697 . E8 543CF8FF call 004452F0
004C169C . 8B55 D8 mov edx, dword ptr [ebp-28]
004C169F . B8 48194C00 mov eax, 004C1948
004C16A4 . E8 E730F4FF call 00404790
004C16A9 . 85C0 test eax, eax
004C16AB 7E 1E jle short 004C16CB
//这里跳转未实现
//004C16CB=004C16CB
004C16AD . 8D55 D4 lea edx, dword ptr [ebp-2C]
004C16B0 . 8B45 FC mov eax, dword ptr [ebp-4]
004C16B3 . 8B80 20030000 mov eax, dword ptr [eax+320]
004C16B9 . E8 323CF8FF call 004452F0
//不理它,继续。
004C16BE . 8B45 D4 mov eax, dword ptr [ebp-2C]
004C16C1 . E8 4212F7FF call 00432908 //提示错误,看来刚才那个就关键的跳转。
好重新载入下断点,再次到此处:
004C16AB 7E 1E jle short 004C16CB
把它修改,JLE改为jmp,直接让它调。
保存修改,运行程序看看效果,结果程序一闪而过,看来不行了,继续。
004C16F5 E8 DEA6F4FF call 0040BDD8
//到此,程序又有错误提示,重新来过,再到这里跟进,跟进一段时间,又提示错误,难道我就这样陷入代
码的苦海!
此时我注意观察
004C16F5 E8 DEA6F4FF call 0040BDD8
下面的代码。
004C16FA 8B45 FC mov eax, dword ptr [ebp-4]
004C16FD DD98 40030000 [color=red]fstp [/color] qword ptr [eax+340]
004C1703 9B wait
004C1704 8D4D C4 lea ecx, dword ptr [ebp-3C]
004C1707 8B45 FC mov eax, dword ptr [ebp-4]
004C170A 8B80 20030000 mov eax, dword ptr [eax+320]
004C1710 8B80 20020000 mov eax, dword ptr [eax+220]
004C1716 BA 02000000 mov edx, 2
004C171B 8B18 mov ebx, dword ptr [eax]
004C171D FF53 0C call dword ptr [ebx+C]
004C1720 8B45 C4 mov eax, dword ptr [ebp-3C]
004C1723 8D55 C8 lea edx, dword ptr [ebp-38]
004C1726 E8 9D6FF4FF call 004086C8
004C172B 8B45 C8 mov eax, dword ptr [ebp-38]
004C172E E8 A5A6F4FF call 0040BDD8
004C1733 8B45 FC mov eax, dword ptr [ebp-4]
004C1736 DD98 48030000 [color=red]fstp[/color] qword ptr [eax+348]
004C173C 9B wait
004C173D 8D4D BC lea ecx, dword ptr [ebp-44]
004C1740 8B45 FC mov eax, dword ptr [ebp-4]
004C1743 8B80 20030000 mov eax, dword ptr [eax+320]
004C1749 8B80 20020000 mov eax, dword ptr [eax+220]
004C174F BA 03000000 mov edx, 3
004C1754 8B18 mov ebx, dword ptr [eax]
004C1756 FF53 0C call dword ptr [ebx+C]
004C1759 8B45 BC mov eax, dword ptr [ebp-44]
004C175C 8D55 C0 lea edx, dword ptr [ebp-40]
004C175F E8 646FF4FF call 004086C8
004C1764 8B45 C0 mov eax, dword ptr [ebp-40]
004C1767 E8 6CA6F4FF call 0040BDD8
004C176C 8B45 FC mov eax, dword ptr [ebp-4]
004C176F DD98 50030000 [color=red]fstp[/color] qword ptr [eax+350]
004C1775 9B wait
004C1776 8B45 FC mov eax, dword ptr [ebp-4]
004C1779 DD80 50030000 fld qword ptr [eax+350]
004C177F 8B45 FC mov eax, dword ptr [ebp-4]
004C1782 DC98 48030000 fcomp qword ptr [eax+348]
004C1788 DFE0 fstsw ax
无有例外都有FSTP,也同样调用
XXXXXXXX E8 646FF4FF [color=red]call 004086C8
[/color]XXXXXXXX 8B45 C0 mov eax, dword ptr [ebp-40]
XXXXXXXX E8 6CA6F4FF [color=red]call 0040BDD8[/color]
那又是什么意思呢?不管是什么,既然前面很多,是不是像障碍一样呢。那好我就全部清理下,死马当活马医。
全部NOP掉,保存修改,运行程序,很幸运通过程序,到此破解完毕!
后记:此次破解过程,是在我多次跟踪,试验后才有的成果。其中的如果有半点浮躁,恐怕也没今日的结
果。学破解就要执着,耐心,浮躁要不得。
对于FSTP命令,我事后查找了一下,就找到一点点:
fild和fstp都是x87指令
fild是将整数转化为长双精FP80压栈(压到st0)
[color=red]fstp是将弹栈指令,将st0弹出。[/color]
没听懂说什么。:sweat: ,哪位大侠指点下小弟。
[[i] 本帖最后由 jacky 于 2008-2-21 15:23 编辑 [/i]] 首先多谢楼主分享Themida脱壳机,
上面文章最后的疑问是指不懂fstp的解释还是?
浮点指令有其专用堆栈,最上面的是st0,依次st1,st2,st3....
st0弹出(出栈pop)后原st1变成st0,如果是压栈操作则当前的st0会变成st1,压入内容变st0。
说得有点乱:loveliness: [quote]原帖由 [i]落叶树[/i] 于 2008-2-21 13:22 发表 [url=http://forum.eviloctal.com/redirect.php?goto=findpost&pid=138825&ptid=32290][img]images/common/back.gif[/img][/url]
首先多谢楼主分享Themida脱壳机,
上面文章最后的疑问是指不懂fstp的解释还是?
浮点指令有其专用堆栈,最上面的是st0,依次st1,st2,st3....
st0弹出(出栈pop)后原st1变成st0,如果是压栈操作则当前的st0会变成st1,压入内容变st ... [/quote]
我是解释也不懂,作用也迷糊。
我只想知道通俗的作用,呵呵,谢谢指点。 浮点指令说明:
[quote]
对下面的指令先做一些说明:
st(i):代表浮点寄存器,所说的出栈、入栈操作都是对st(i)的影响
src,dst,dest,op等都是指指令的操作数,src表示源操作数,dst/dest表示目的操作数
mem8,mem16,mem32,mem64,mem80等表示是内存操作数,后面的数值表示该操作数的内存位数(8位为一字节)
x <- y 表示将y的值放入x,例st(0) <- st(0) - st(1)表示将st(0)-st(1)的值放入浮点寄存器st(0)
1. 数据传递和对常量的操作指令
指令格式
指令含义
执行的操作
FLD src
装入实数到st(0)
st(0) <- src (mem32/mem64/mem80)
FILD src
装入整数到st(0)
st(0) <- src (mem16/mem32/mem64)
FBLD src
装入BCD数到st(0)
st(0) <- src (mem80)
FLDZ
将0.0装入st(0)
st(0) <- 0.0
FLD1
将1.0装入st(0)
st(0) <- 1.0
FLDPI
将pi装入st(0)
st(0) <- ?(ie, pi)
FLDL2T
将log2(10)装入st(0)
st(0) <- log2(10)
FLDL2E
将log2(e)装入st(0)
st(0) <- log2(e)
FLDLG2
将log10(2)装入st(0)
st(0) <- log10(2)
FLDLN2
将loge(2)装入st(0)
st(0) <- loge(2)
FST dest
保存实数st(0)到dest
dest <- st(0) (mem32/mem64)
FSTP dest
dest <- st(0) (mem32/mem64/mem80);然后再执行一次出栈操作
FIST dest
将st(0)以整数保存到dest
dest <- st(0) (mem32/mem64)
FISTP dest
dest <- st(0) (mem16/mem32/mem64);然后再执行一次出栈操作
FBST dest
将st(0)以BCD保存到dest
dest <- st(0) (mem80)
FBSTP dest
dest<- st(0) (mem80);然后再执行一次出栈操作
2.比较指令
指令格式
指令含义
执行的操作
FCOM
实数比较
将标志位设置为 st(0) - st(1) 的结果标志位
FCOM op
实数比较
将标志位设置为 st(0) - op (mem32/mem64)的结果标志位
FICOM op
和整数比较
将Flags值设置为st(0)-op 的结果op (mem16/mem32)
FICOMP op
和整数比较
将st(0)和op比较 op(mem16/mem32)后;再执行一次出栈操作
FTST
零检测
将st(0)和0.0比较
FUCOM st(i)
比较st(0) 和st(i) [486]
FUCOMP st(i)
比较st(0) 和st(i),并且执行一次出栈操作
FUCOMPP st(i)
比较st(0) 和st(i),并且执行两次出栈操作
FXAM
Examine: Eyeball st(0) (set condition codes)
3.运算指令
指令格式
指令含义
执行的操作
加法
FADD
加实数
st(0) <-st(0) + st(1)
FADD src
st(0) <-st(0) + src (mem32/mem64)
FADD st(i),st
st(i) <- st(i) + st(0)
FADDP st(i),st
st(i) <- st(i) + st(0);然后执行一次出栈操作
FIADD src
加上一个整数
st(0) <-st(0) + src (mem16/mem32)
减法
FSUB
减去一个实数
st(0) <- st(0) - st(1)
FSUB src
st(0) <-st(0) - src (reg/mem)
FSUB st(i),st
st(i) <-st(i) - st(0)
FSUBP st(i),st
st(i) <-st(i) - st(0),然后执行一次出栈操作
FSUBR st(i),st
用一个实数来减
st(0) <- st(i) - st(0)
FSUBRP st(i),st
st(0) <- st(i) - st(0),然后执行一次出栈操作
FISUB src
减去一个整数
st(0) <- st(0) - src (mem16/mem32)
FISUBR src
用一个整数来减
st(0) <- src - st(0) (mem16/mem32)
乘法
FMUL
乘上一个实数
st(0) <- st(0) * st(1)
FMUL st(i)
st(0) <- st(0) * st(i)
FMUL st(i),st
st(i) <- st(0) * st(i)
FMULP st(i),st
st(i) <- st(0) * st(i),然后执行一次出栈操作
FIMUL src
乘上一个整数
st(0) <- st(0) * src (mem16/mem32)
除法
FDIV
除以一个实数
st(0) <-st(0) /st(1)
FDIV st(i)
st(0) <- st(0) /t(i)
FDIV st(i),st
st(i) <-st(0) /st(i)
FDIVP st(i),st
st(i) <-st(0) /st(i),然后执行一次出栈操作
FIDIV src
除以一个整数
st(0) <- st(0) /src (mem16/mem32)
FDIVR st(i),st
用实数除
st(0) <- st(i) /st(0)
FDIVRP st(i),st
FDIVRP st(i),st
FIDIVR src
用整数除
st(0) <- src /st(0) (mem16/mem32)
FSQRT
平方根
st(0) <- sqrt st(0)
FSCALE
2的st(0)次方
st(0) <- 2 ^ st(0)
FXTRACT
Extract exponent:
st(0) <-exponent of st(0); and gets pushed
st(0) <-significand of st(0)
FPREM
取余数
st(0) <-st(0) MOD st(1)
FPREM1
取余数(IEEE),同FPREM,但是使用IEEE标准[486]
FRNDINT
取整(四舍五入)
st(0) <- INT( st(0) ); depends on RC flag
FABS
求绝对值
st(0) <- ABS( st(0) ); removes sign
FCHS
改变符号位(求负数)
st(0) <-st(0)
F2XM1
计算(2 ^ x)-1
st(0) <- (2 ^ st(0)) - 1
FYL2X
计算Y * log2(X)
st(0)为Y;st(1)为X;将st(0)和st(1)变为st(0) * log2( st(1) )的值
FCOS
余弦函数Cos
st(0) <- COS( st(0) )
FPTAN
正切函数tan
st(0) <- TAN( st(0) )
FPATAN
反正切函数arctan
st(0) <- ATAN( st(0) )
FSIN
正弦函数sin
st(0) <- SIN( st(0) )
FSINCOS
sincos函数
st(0) <-SIN( st(0) ),并且压入st(1)
st(0) <- COS( st(0) )
FYL2XP1
计算Y * log2(X+1)
st(0)为Y; st(1)为X; 将st(0)和st(1)变为st(0) * log2( st(1)+1 )的值
处理器控制指令
FINIT
初始化FPU
FSTSW AX
保存状态字的值到AX
AX<- MSW
FSTSW dest
保存状态字的值到dest
dest<-MSW (mem16)
FLDCW src
从src装入FPU的控制字
FPU CW <-src (mem16)
FSTCW dest
将FPU的控制字保存到dest
dest<- FPU CW
FCLEX
清除异常
FSTENV dest
保存环境到内存地址dest处 保存状态字、控制字、标志字和异常指针的值
FLDENV src
从内存地址src处装入保存的环境
FSAVE dest
保存FPU的状态到dest处 94字节
FRSTOR src
从src处装入由FSAVE保存的FPU状态
FINCSTP
增加FPU的栈指针值
st(6) <-st(5); st(5) <-st(4),...,st(0) <-?
FDECSTP
减少FPU的栈指针值
st(0) <-st(1); st(1) <-st(2),...,st(7) <-?
FFREE st(i)
标志寄存器st(i)未被使用
FNOP
空操作,等同CPU的nop
st(0) <-st(0)
WAIT/FWAIT
同步FPU与CPU:停止CPU的运行,直到FPU完成当前操作码
FXCH
交换指令,交换st(0)和st(1)的值
st(0) <-st(1)
st(1) <- st(0)
[/quote]
页:
[1]