测试VM
本帖最后由 mochongli 于 2022-12-30 18:51 编辑vmp超级,保护全关。
本帖最后由 成熟的美羊羊 于 2023-1-29 19:09 编辑
## 手动快速定位not_not_and及eflag出现的地址
#### 感谢Cpudbg前辈(一个国产全栈调试器作者)的帮助,让我理解到了模板的概念,可以通过模板快速的定位handler分析vm虚拟机。
根据CpuDbg前辈在群里发的使用搜索命令序列定位handler vmp3.x爆破视频和论坛以往的帖子得到了一条信息。
VMP在模拟cmp和jcc指令时会出现如下指令。
出现这样的情况,将282 改成 246就算是通过修改eflag进行修改跳转了。
具体的学习可以通过论坛 鱼无伦次前辈的VMP学习笔记来研究。
https://www.52pojie.cn/thread-1036956-1-1.html
```
mov reg, eflag 282 -> 246
mov reg, xxx(忘记叫什么了) 40
not reg
not reg
and reg,reg
```
这样的指令执行了VMP not_not_and的功能,可以当作VMP的handle 模板来使用
### 通过Trace文件进行分析
#### 打开Trace功能
输入假码“9999999999999”,在0000000140139113下断点,打开Trace功能后在0000000140139118,00000001401391BC下断点
![打开Trace功能](http://imgsrc.baidu.com/super/pic/item/6f061d950a7b020866c0ca2527d9f2d3562cc8ed.jpg)
#### 开始跟踪
Ctrl+Alt+F7 进行步进跟踪,最大单步次数设置为:100000
![开启步进跟踪](http://imgsrc.baidu.com/super/pic/item/500fd9f9d72a60596e6d14de6d34349b023bbaf1.jpg)
等待片刻,程序断在了00000001401391BC 失败处
![](http://imgsrc.baidu.com/super/pic/item/5ab5c9ea15ce36d3817d76f47ff33a87e850b1fd.jpg)
#### 分析Trace文件
在跟踪窗口右键,保存Trace文件,文件名为:"TraceLog.txt"
![保存Trace文件](http://imgsrc.baidu.com/super/pic/item/f603918fa0ec08fa7a75e6631cee3d6d54fbdaf9.jpg)
正则表达式搜索如下文本,通过它来寻找nor64指令,假设CrackMe作者加壳后的程序主要是通过not_not_and_64来运行的。
```
nor64:mov .*,qword ptr ds:\[.*\+.*\].*-> 2
nor32:mov .*,dword ptr ds:\[.*\+.*\].*-> 2
nor16:mov .*,word ptr ds:\[.*\+.*\].*-> 2
nor:mov .*,.*\[.*\+.*\].*-> 2
```
可以看到,搜索到的结果有11个,我们从下往上找
第11个如图,是not_not_and指令,其位于TraceLog中B481序号。回到X96Dbg对序号为B481的地址:0000000140081C16下断点。图片上传错了,不清楚该如何恢复。。有机会改下。
![](http://imgsrc.baidu.com/super/pic/item/9f510fb30f2442a73a6508619443ad4bd013028f.jpg)
将293 -> 246,程序走到了正确的地址,继续F9
![](http://imgsrc.baidu.com/super/pic/item/aa64034f78f0f7365db6b9c54f55b319eac413ae.jpg)
程序异常了,不清楚原因是啥,但是我们可以继续测试上一条nor指令
![](http://imgsrc.baidu.com/super/pic/item/ac6eddc451da81cbedab76091766d016082431a1.jpg)
第10个如图,是not_not_and指令,其地址是00000001400C6867
![](http://imgsrc.baidu.com/super/pic/item/58ee3d6d55fbb2fb726cadd60a4a20a44723dcab.jpg)
我们在00000001400C6867地址下断点,将rax 282->246,F9运行,成功了
![](http://imgsrc.baidu.com/super/pic/item/aa64034f78f0f7365d40b9c54f55b319eac413bc.jpg)
### 为什么通过Trace文件分析,还要手动定位handle?
因为没写脚本,通过写脚本定位handle是非常快速的。写好后会发在论坛。
### 为什么使用mov .*,qword ptr ds:\[.*\+.*\].*-> 2定位not_not_and指令?
因为没写脚本,其次就是虽然not_not_and指令这个名字就是这个handle最特殊的地方,但是not reg与and reg指令出现过多,使得通过VMP对堆栈取值的指令来定位not_not_and指令在手动定位方面上更快。
## 通过hook的方式来穷举出答案
因为在跟踪字符串与函数调用的时候,发现程序只使用了atoi指令将字符串转换为整数,同时程序在VM了状态下速度极快。
所以猜测算法复杂度很小,通过hook的方式循环测试,测出64,81是正确的password,注意到“D”了嘛,程序在运行到正确的地址时,把64参与运算的最终结果也给输出出来了,
结合楼主给的password:“13” 可以推测出13就是cmp比较的值,至于中间的运算过程,可以通过这两条正则表达式进行数据的跟踪从而推测出中间运算过程,
可能搜索的操作数大小 需要改成dword,慢慢测试就好了。
```
mov .*,qword ptr ds:\[.*\+.*\].*-> D("13")"这里添加一个空格"end
mov .*,qword ptr ds:\[.*\+.*\].*-> atoi(你输入的password("999999999999"))"这里添加一个空格"end
```
![](http://imgsrc.baidu.com/super/pic/item/838ba61ea8d3fd1fefad57fe754e251f94ca5f4a.jpg)
![](http://imgsrc.baidu.com/super/pic/item/aec379310a55b3191d5e77b106a98226cefc174b.jpg)
## 手动hook实现补丁
判断下是否是eflag就好了,比较暴力,部分机器可能运行失败,上传文件为Cracked.rar
![](http://imgsrc.baidu.com/super/pic/item/1f178a82b9014a900ee6b479ec773912b21bee1f.jpg)
## 编写脚本进行辅助人肉还原-未完待续。
可能会过很久更新,或者不更了,哈哈,比较懒。-2023年1月2日16点02分
电脑意外报废,脚本编写了大部分。打算用手机写。2023年1月22日
尴尬的是,通知上学了,怕是短时间完成不了了。先发一部分代码好了,代码很简单。
--常用的handler识别
function string2table(s)
local t={}
for i=1,string.len(s) do
table.insert(t,string.sub(s,i,i))
end
return t
end
------------------简单模型-----------------
--读
f=io.open("/storage/emulated/0/zhouqing/2222.csv","r+")
f2=io.open("/storage/emulated/0/zhouqing/1.txt","w+")
f2=io.open("/storage/emulated/0/zhouqing/1.txt","a+")
patter = "mov .*,.*%[.*%+.%]"
--patter = "mov .*,.*%[.*%+8%]"
patter2 = "mov .*,.*%[[^%+]+%]"
patter3 = "mov (%w+),"
patter4 = "(%a+) "
--patter = "mov .*,.*%[.*%]"
test = "mov"
t = {}
line_count = 0
for line in f:lines() do
line_count = line_count+1
table.insert(t,line_count,line)
end
for i = 1,#t do
local str = string.match(t,patter)
if str ~= nil then
local beOperand = string.match(t,patter3)
--往上十条语句如果含有patter2,那么就是运算handler
for ecx = 1,10 do
local str2 = string.match(t,patter2)
if str2 ~= nil then
local beOperand2 = string.match(t,patter3)
--local beOperand2 = string.match(t,patter3)
--print(beOperand2)
f2:write(t)
--f2:write(str2)
f2:write("\n")
f2:write(t)
--f2:write(str)
f2:write("\n")
for ecx2 = 1,30 do
local str3 = string.match(t,beOperand2)
local flag = 0
-- print(beOperand2)
if str3 == nil then
str3 = string.match(t,beOperand)
if str3 == nil then
str3 = string.match(t,"push")
if str3 == nil then
str3 = string.match(t,"pop")
if str3 ~= nil then
flag = 1
--f2:write(str2)
--f2:write(str3)
f2:write(t)
f2:write("\n")
f2:write("\n")
break
end
else
flag = 1
end
else
flag = 1
end
else
flag = 1
end
if flag == 1 then
str3 = string.match(t,patter4)
--f2:write(str3)
f2:write(t)
f2:write("\n")
end
end
f2:flush()
break
end
end
--print(type(line))
end
end
f2:close()
print("process end")
A6ED,00000001400603E1,48:F7D3,not rbx,rbx: FFFFFFFFFFFFF7EA-> 815,,
A6F1,00000001400603EF,48:F7D0,not rax,rax: FFFFFFFFFFFFFDE8-> 217,,
A6F2,00000001400603F2,48:23D8,"and rbx,rax",rbx: 815-> 15,,
A6F4,00000001400603F8,49:8958 08,"mov qword ptr ds:,rbx",,000000000014FDF8: FFFFFFFFFFFFFDE8-> 15,"r8+8:""word:"""
A6F5,00000001400603FC,9C,pushfq ,rsp: 14FBE0-> 14FBD8,000000000014FBD8: 1400603CE-> 202,
A6F7,0000000140060400,41:8F00,pop qword ptr ds:,rsp: 14FBD8-> 14FBE0,000000000014FDF0: FFFFFFFFFFFFF7EA-> 202 000000000014FBD8: 202-> 202,
A7CC,00000001400C6847,49:8B18,"mov rbx,qword ptr ds:",rbx: 15-> 286,000000000014FDE8: 286-> 286,
A7CD,00000001400C684A,49:8B40 08,"mov rax,qword ptr ds:",rax: 14FD20-> 286,000000000014FDF0: 286-> 286,"r8+8:""word:"""
A7D1,00000001400C685A,48:F7D3,not rbx,rbx: 286-> FFFFFFFFFFFFFD79,,
A7D5,00000001400C6867,48:F7D0,not rax,rax: 286-> FFFFFFFFFFFFFD79,,
A7D6,00000001400C686A,48:23D8,"and rbx,rax",,,
A7D7,00000001400C686D,49:8958 08,"mov qword ptr ds:,rbx",,000000000014FDF0: 286-> FFFFFFFFFFFFFD79,"r8+8:""word:"""
A7DB,00000001400C687D,9C,pushfq ,rsp: 14FBE0-> 14FBD8,000000000014FBD8: 1400C6847-> 282,
A7DC,00000001400C687E,41:8F00,pop qword ptr ds:,rsp: 14FBD8-> 14FBE0,000000000014FDE8: 286-> 282 000000000014FBD8: 282-> 282,
A861,00000001400B785B,49:8B18,"mov rbx,qword ptr ds:",,000000000014FDE8: 815-> 815,
A864,00000001400B7866,49:8B40 08,"mov rax,qword ptr ds:",rax: 14FD01-> FFFFFFFFFFFFFD79,000000000014FDF0: FFFFFFFFFFFFFD79-> FFFFFFFFFFFFFD79,"r8+8:""word:"""
A868,00000001400B7878,48:F7D3,not rbx,rbx: 815-> FFFFFFFFFFFFF7EA,,
A869,00000001400B787B,48:F7D0,not rax,rax: FFFFFFFFFFFFFD79-> 286,,
A86C,00000001400B7886,48:23D8,"and rbx,rax",rbx: FFFFFFFFFFFFF7EA-> 282,,
A86D,00000001400B7889,49:8958 08,"mov qword ptr ds:,rbx",,000000000014FDF0: FFFFFFFFFFFFFD79-> 282,"r8+8:""word:"""
A871,00000001400B7899,9C,pushfq ,rsp: 14FBE0-> 14FBD8,000000000014FBD8: 1400B785B-> 206,
A872,00000001400B789A,48:0BEB,"or rbp,rbx",rbp: FFFFA875-> FFFFAAF7,,
A873,00000001400B789D,41:8F00,pop qword ptr ds:,rsp: 14FBD8-> 14FBE0,000000000014FDE8: 815-> 206 000000000014FBD8: 206-> 206,
A8CC,0000000140073995,49:8B08,"mov rcx,qword ptr ds:",rcx: 98-> 282,000000000014FDF0: 282-> 282,
A8CD,0000000140073998,49:8B68 08,"mov rbp,qword ptr ds:",rbp: 206-> 15,000000000014FDF8: 15-> 15,
A8D1,00000001400739A4,48:03CD,"add rcx,rbp",rcx: 282-> 297,,
A8D2,00000001400739A7,49:8948 08,"mov qword ptr ds:,rcx",,000000000014FDF8: 15-> 297,"r8+8:""word:"""
A8D6,00000001400739B3,9C,pushfq ,rsp: 14FBE0-> 14FBD8,000000000014FBD8: 140073995-> 202,
A8D9,00000001400739BC,41:8F00,pop qword ptr ds:,rsp: 14FBD8-> 14FBE0,000000000014FDF0: 282-> 202 000000000014FBD8: 202-> 202,
cmp eflag calc
darksied 发表于 2023-1-3 10:42
请问:输入假码“9999999999999”,在0000000140139113下断点,打开Trace功能后在0000000140139118,0000 ...
这两个地址,根据X96Dbg的反汇编结果可以看到是两个字符串
0000000140139118 | C5FC2805 60A0ECFF| vmovaps ymm0,yword ptr ds: | 0000000140003180:"Correct password"
00000001401391BC | C5FC2805 9C9FECFF| vmovaps ymm0,yword ptr ds: | 0000000140003160:"Incorrect password"
VMP对vmovaps这类浮点数指令支持不好,使得我们可以通过观察反汇编窗口定位可疑字符,进行
定位。
这两个地址下断点的用途,是为了让X96Dbg不要跟踪太久,生成太大的log。如果电脑配置够好,可以直接在ExitProcess下断点 成熟的美羊羊 发表于 2023-1-1 23:14
## 手动快速定位not_not_and及eflag出现的地址
#### 感谢Cpudbg前辈(一个国产全栈调试器作者)的帮助 ...
请问:输入假码“9999999999999”,在0000000140139113下断点,打开Trace功能后在0000000140139118,00000001401391BC下断点这几个断点是怎么确定的?
页:
[1]