邪恶八进制信息安全团队技术讨论组's Archiver

jacky 2008-2-21 11:46

[原创]对某外挂的再次破解

文章作者: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]]

落叶树 2008-2-21 13:22

首先多谢楼主分享Themida脱壳机,
上面文章最后的疑问是指不懂fstp的解释还是?
浮点指令有其专用堆栈,最上面的是st0,依次st1,st2,st3....
st0弹出(出栈pop)后原st1变成st0,如果是压栈操作则当前的st0会变成st1,压入内容变st0。
说得有点乱:loveliness:

jacky 2008-2-21 14:03

[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]
我是解释也不懂,作用也迷糊。
我只想知道通俗的作用,呵呵,谢谢指点。

落叶树 2008-2-21 14:31

浮点指令说明:
[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]
© 1999-2008 EvilOctal Security Team