当前位置:网站首页>[网鼎杯 2020 青龙组]singal
[网鼎杯 2020 青龙组]singal
2022-08-02 04:26:00 【雨后初霁&】
[网鼎杯 2020 青龙组]singal-简单的vm逆向
[网鼎杯 2020 青龙组]singal
最近在补汇编和win32api,算法也开始在弄,题目做得少。之前也写过vm的题,记录写得少,这里记录一篇
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4[117]; // [esp+18h] [ebp-1D4h] BYREF
__main();
qmemcpy(v4, byte_403040, 0x1C8u);
vm_operad(v4, 114);
puts("good,The answer format is:flag {}");
return 0;
}
很明显,byte_403040里面就是指令,把byte合成int 给到v4,然后进入vm_operad函数操作
关键函数进行审计
void __cdecl vm_operad(int *a1, int a2)
{
char Str[200]; // [esp+13h] [ebp-E5h] BYREF
char v3; // [esp+DBh] [ebp-1Dh]
int v4; // [esp+DCh] [ebp-1Ch]
int v5; // [esp+E0h] [ebp-18h]
int v6; // [esp+E4h] [ebp-14h]
int v7; // [esp+E8h] [ebp-10h]
int v8; // [esp+ECh] [ebp-Ch]
v8 = 0;
v7 = 0;
v6 = 0;
v5 = 0;
v4 = 0;
LABEL_2:
while ( v8 < a2 )
{
switch ( a1[v8] )
{
case 1:
Str[v5 + 100] = v3;
++v8;
++v5;
++v7;
break;
case 2:
v3 = a1[v8 + 1] + Str[v7];
v8 += 2;
break;
case 3:
v3 = Str[v7] - LOBYTE(a1[v8 + 1]);
v8 += 2;
break;
case 4:
v3 = a1[v8 + 1] ^ Str[v7];
v8 += 2;
break;
case 5:
v3 = a1[v8 + 1] * Str[v7];
v8 += 2;
break;
case 6:
++v8;
break;
case 7:
if ( Str[v6 + 100] != a1[v8 + 1] )
{
printf("what a shame...");
exit(0);
}
++v6;
v8 += 2;
break;
case 8:
Str[v4] = v3;
++v8;
++v4;
break;
case 10:
read(Str);
++v8;
break;
case 11:
v3 = Str[v7] - 1;
++v8;
break;
case 12:
v3 = Str[v7] + 1;
++v8;
break;
default:
goto LABEL_2;
}
}
}
我们在Read中发现flag是15位,考虑copy下来来模拟一次
#include <stdio.h>
#include <windows.h>
unsigned char enc[] =
{
0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x00,
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00,
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xFF, 0xFF,
0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x84, 0xFF,
0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC1, 0xFF, 0xFF, 0xFF,
0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
unsigned int *enc1 = (unsigned int*)enc;
void __cdecl vm_operad(unsigned int* a1, int a2);
char Str[200] = "123456789123456";
int main(void) {
for (int i = 0; i < 128; i++) {
printf("%d ", enc1[i]);
}
printf("\n");
vm_operad(enc1, 114);
return 0;
}
void __cdecl vm_operad(unsigned int* a1, int a2)
{
//char Str[200]; // [esp+13h] [ebp-E5h] BYREF
char v3; // [esp+DBh] [ebp-1Dh]
int v4; // [esp+DCh] [ebp-1Ch]
int v5; // [esp+E0h] [ebp-18h]
int v6; // [esp+E4h] [ebp-14h]
int v7; // [esp+E8h] [ebp-10h]
int v8; // [esp+ECh] [ebp-Ch]
v8 = 0;
v7 = 0;
v6 = 0;
v5 = 0;
v4 = 0;
LABEL_2:
while (v8 < a2)
{
switch (a1[v8])
{
case 1:
Str[v5 + 100] = v3;
printf("encode[%d]=%d\n", v5, v3);
printf("\n");
++v8;
++v5;
++v7;
break;
case 2:
v3 = a1[v8 + 1] + Str[v7];
printf("%d = %d + input[%d](%d)\n",v3, a1[v8 + 1], v7,Str[v7]);
v8 += 2;
break;
case 3:
v3 = Str[v7] - LOBYTE(a1[v8 + 1]);
printf("%d = input[%d](%d)-%d\n", v3, v7,Str[v7], LOBYTE(a1[v8 + 1]));
v8 += 2;
break;
case 4:
v3 = a1[v8 + 1] ^ Str[v7];
printf("%d = %d^input[%d](%d) \n",v3, a1[v8 + 1],v7, Str[v7]);
v8 += 2;
break;
case 5:
v3 = a1[v8 + 1] * Str[v7];
printf("%d = %d*input[%d](%d)\n",v3, a1[v8 + 1],v7, Str[v7]);
v8 += 2;
break;
case 6:
++v8;
break;
case 7:
printf("encode[%d](%d) ! = enc[%d](%d)\n",v6, Str[v6 + 100],v6, a1[v8 + 1]);
if (Str[v6 + 100] != a1[v8 + 1])
{
printf("what a shame...\n");
/*exit(0);*/
}
++v6;
v8 += 2;
break;
case 8:
Str[v4] = v3;
printf("input[%d]=%d\n",v4,v3);
++v8;
++v4;
break;
case 10:
/*read(Str);*/
++v8;
break;
case 11:
v3 = Str[v7] - 1;
printf("%d = input[%d](%d)-1\n",v3,v7,Str[v7]);
++v8;
break;
case 12:
v3 = Str[v7] + 1;
printf("%d = input[%d](%d)+1\n", v3, v7,Str[v7]);
++v8;
break;
default:
goto LABEL_2;
}
}
}
得到
33 = 16^input[0](49)
input[0]=33
28 = input[0](33)-5
encode[0]=28
18 = 32^input[1](50)
input[1]=18
54 = 3*input[1](18)
encode[1]=54
49 = input[2](51)-2
input[2]=49
48 = input[2](49)-1
encode[2]=48
53 = input[3](52)+1
input[3]=53
49 = 4^input[3](53)
encode[3]=49
159 = 3*input[4](53)
input[4]=159
-130 = input[4](-97)-33
encode[4]=-130
53 = input[5](54)-1
input[5]=53
52 = input[5](53)-1
encode[5]=52
62 = 9^input[6](55)
input[6]=62
30 = input[6](62)-32
encode[6]=30
137 = 81 + input[7](56)
input[7]=137
-83 = 36^input[7](-119)
encode[7]=-83
58 = input[8](57)+1
input[8]=58
57 = input[8](58)-1
encode[8]=57
98 = 2*input[9](49)
input[9]=98
135 = 37 + input[9](98)
encode[9]=135
104 = 54 + input[10](50)
input[10]=104
41 = 65^input[10](104)
encode[10]=41
83 = 32 + input[11](51)
input[11]=83
83 = 1*input[11](83)
encode[11]=83
156 = 3*input[12](52)
input[12]=156
-63 = 37 + input[12](-100)
encode[12]=-63
60 = 9^input[13](53)
input[13]=60
28 = input[13](60)-32
encode[13]=28
119 = 65 + input[14](54)
input[14]=119
120 = input[14](119)+1
encode[14]=120
encode[0](28) ! = enc[0](34)
what a shame...
encode[1](54) ! = enc[1](63)
what a shame...
encode[2](48) ! = enc[2](52)
what a shame...
encode[3](49) ! = enc[3](50)
what a shame...
encode[4](126) ! = enc[4](114)
what a shame...
encode[5](52) ! = enc[5](51)
what a shame...
encode[6](30) ! = enc[6](24)
what a shame...
encode[7](-83) ! = enc[7](-89)
what a shame...
encode[8](57) ! = enc[8](49)
what a shame...
encode[9](-121) ! = enc[9](-15)
what a shame...
encode[10](41) ! = enc[10](40)
what a shame...
encode[11](83) ! = enc[11](-124)
what a shame...
encode[12](-63) ! = enc[12](-63)
encode[13](28) ! = enc[13](30)
what a shame...
encode[14](120) ! = enc[14](122)
what a shame...
我们进行代码量少,我们可以手动恢复
EXP
enc=[34,63,52,50,114,51,24,-89,49,-15,40,-124,-63,30,122]
for i in range(len(enc)):
if enc[i]<0:
enc[i]=0xff&enc[i]-1#有负数,char类型取补码就行了
enc[0]=(enc[0]+5)^16
enc[1]=(enc[1]//3)^32
enc[2]=(enc[2]+1+2)
enc[3]=(enc[3]^4)-1
enc[4]=(enc[4]+33)//3
enc[5]=(enc[5])+2
enc[6]=(enc[6]+32)^9
enc[7]=(enc[7]^36)-81
enc[8]=(enc[8])
enc[9]=(enc[9]-37)//2
enc[10]=(enc[10]^65)-54
enc[11]=(enc[11]-32)
enc[12]=(enc[12]-37)//3
enc[13]=(enc[13]+32)^9
enc[14]=(enc[14]-1-65)
print(bytes(enc))
# b'757515121f3d478'
边栏推荐
猜你喜欢
Anatomy of Unreal Playback System (Part 1)
2022-08-01:以下go语言代码输出什么?A:panic;B:5;C:6;D:编译错误。 package main import ( “fmt“ ) func main() {
internship:数据库表和建立的实体类及对应的枚举类之间的联系示例
UE4 事件图表不小心拉了很远,找不到一开始创建的节点
batch_size of deep learning foundation
The line chart with square PyQt5_pyqtgraph mouse
AFMG SysTune1.3.7使用图解
线代005
如何让固定点的监控设备在EasyCVR平台GIS电子地图上显示地理位置?
1318_将ST link刷成jlink
随机推荐
来自雪域高原的馈赠——大凉山高原生态糖心苹果
(一)代码输出题 —— reverse
Qt处理传输协议数据时QByteArray添加多字节的使用案例
LeetCode 23: 合并K个升序链表
【STM32】 ADC模数转换
递归实现排列型枚举(DAY 93)
质数路径(DAY 99)
列表总结
A Practical Arrangement of Map GIS Development Matters (Part 1)
2022 Huawei Software Elite Challenge (Preliminary) - Summary
力扣练习——44 路径总和 III
CaDDN code debugging
AFMG SysTune1.3.7使用图解
C语言可以应用在哪些领域?
单调队列模板 滑动窗口
Scala basics [common method supplement, pattern matching]
300M级mysql数据库跨版本迁移流程
Sentinel熔断之非控制台方式总结
EasyCVR视频广场切换通道,视频播放协议异常的问题修复
ZCMU--1891: kotomi and game(C语言)