当前位置:网站首页>ReversingKr-wp(7)
ReversingKr-wp(7)
2022-07-18 13:02:00 【fa1c4】
x64 Lotto

無殼直接分析, 這是一個隨機數猜測的程序, 猜對了給flag
__int64 wmain()
{
unsigned int v0; // eax
__int64 i; // rbx
char v2; // r8
int v3; // edx
__int64 v4; // rcx
_BYTE *v5; // rdx
__int64 v6; // rcx
char v7; // al
int v8; // ecx
__int16 *v9; // rdx
__int16 v10; // ax
__int16 v11; // ax
int v13; // [rsp+40h] [rbp-78h] BYREF
int v14; // [rsp+44h] [rbp-74h] BYREF
int v15; // [rsp+48h] [rbp-70h] BYREF
int v16; // [rsp+4Ch] [rbp-6Ch] BYREF
int v17; // [rsp+50h] [rbp-68h] BYREF
int v18; // [rsp+54h] [rbp-64h] BYREF
int v19[3]; // [rsp+58h] [rbp-60h]
int v20; // [rsp+64h] [rbp-54h]
int v21; // [rsp+68h] [rbp-50h]
int v22; // [rsp+6Ch] [rbp-4Ch]
__int16 flagstr[25]; // [rsp+70h] [rbp-48h] BYREF
__int16 v24; // [rsp+A2h] [rbp-16h]
v13 = 0;
v14 = 0;
v15 = 0;
v16 = 0;
v17 = 0;
v18 = 0;
v19[0] = 0;
v19[1] = 0;
v19[2] = 0;
v20 = 0;
v21 = 0;
v22 = 0;
v0 = time64(0i64);
srand(v0);
do
{
wprintf(L"\n\t\tL O T T O\t\t\n\n");
wprintf(L"Input the number: ");
wscanf_s(L"%d %d %d %d %d %d", &v13, &v14, &v15, &v16, &v17, &v18);
wsystem(L"cls");
Sleep(0x1F4u);
for ( i = 0i64; i < 6; *(&v18 + i) = rand() % 100 )
++i;
v2 = 1;
v3 = 0;
v4 = 0i64;
byte_1400035F0 = 1;
while ( v19[v4] == *(int *)((char *)&v13 + v4 * 4) )
{
++v4;
++v3;
if ( v4 >= 6 )
goto LABEL_9;
}
v2 = 0;
byte_1400035F0 = 0;
LABEL_9:
;
}
while ( v3 != 6 );
v5 = byte_140003021;
flagstr[1] = 92;
flagstr[0] = 184;
flagstr[2] = 139;
flagstr[5] = 184;
flagstr[3] = 107;
v6 = 0i64;
flagstr[4] = 66;
flagstr[6] = 56;
flagstr[7] = 237;
flagstr[8] = 219;
flagstr[9] = 91;
flagstr[10] = 129;
flagstr[11] = 41;
flagstr[12] = 160;
flagstr[13] = 126;
flagstr[14] = 80;
flagstr[15] = 140;
flagstr[16] = 27;
flagstr[17] = 134;
flagstr[18] = 245;
flagstr[19] = 2;
flagstr[20] = 85;
flagstr[21] = 33;
flagstr[22] = 12;
flagstr[23] = 14;
flagstr[24] = 242;
v24 = 0;
do
{
v7 = byte_140003021[v6 - 1];
v6 += 5i64;
*((_WORD *)&v20 + v6 + 1) ^= (unsigned __int8)(v7 - 12);
*((_WORD *)&v21 + v6) ^= (unsigned __int8)(byte_140003021[v6 - 5] - 12);
*((_WORD *)&v21 + v6 + 1) ^= (unsigned __int8)(byte_140003021[v6 - 4] - 12);
*((_WORD *)&v22 + v6) ^= (unsigned __int8)(byte_140003021[v6 - 3] - 12);
*((_WORD *)&v22 + v6 + 1) ^= (unsigned __int8)(byte_140003021[v6 - 2] - 12);
}
while ( v6 < 25 );
if ( v2 )
{
v8 = 0;
v9 = flagstr;
do
{
v10 = *v9++;
v11 = v8++ + (v10 ^ 0xF);
*(v9 - 1) = v11;
}
while ( v8 < 25 );
v24 = 0;
wprintf(L"%s\n", flagstr);
}
wprintf(L"\n", v5);
return 1i64;
}
發現是內含的flag, 可以動調到flag的wprintf處直接得到flag
雖然這裏只用兩個字"動調"就帶過去了, 其實省略了1個小時的調試過程描述, 需要從IDA反匯編中定比特到3個關鍵跳轉點, nop或者劫持以繞過條件驗證, 最後抵達flag輸出比特置, 文字描述其實意義不大, 就像趙四大佬說的"少動腦多動手"調試起來才能明白.
這三個關鍵跳轉是

CSHARP
工具鏈接: https://github.com/dnSpy/dnSpy/releases
C#, .net逆向, dnSpy打開, 需要動調來破解程序, 先熟悉一下快捷鍵
單步步入:F11
單步步過:F10
執行至斷點:shift+F11
下斷點:F9

發現MetMetMet比較特殊, 進去分析發現是判斷的主邏輯
// CSharp.Form1
// Token: 0x06000005 RID: 5 RVA: 0x00002424 File Offset: 0x00000624
private static void MetMetMet(string sss)
{
byte[] bytes = Encoding.ASCII.GetBytes(Convert.ToBase64String(Encoding.ASCII.GetBytes(sss)));
AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
TypeBuilder typeBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave).DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".exe").DefineType("RevKrT1", TypeAttributes.Public);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("MetMet", MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, null, null);
TypeBuilder typeBuilder2 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave).DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".exe").DefineType("RevKrT2", TypeAttributes.Public);
typeBuilder2.DefineMethod("MetM", MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, null, new Type[]
{
typeof(byte[]),
typeof(byte[])
}).CreateMethodBody(Form1.bb, Form1.bb.Length);
Type type = typeBuilder2.CreateType();
MethodInfo method = type.GetMethod("MetM", BindingFlags.Static | BindingFlags.NonPublic);
object obj = Activator.CreateInstance(type);
byte[] array = new byte[]
{
1,
2
};
method.Invoke(obj, new object[]
{
array,
bytes
});
string str;
if (array[0] == 1)
{
str = "Wrong";
}
else
{
str = "Correct!!";
}
ILGenerator ilgenerator = methodBuilder.GetILGenerator();
ilgenerator.Emit(OpCodes.Ldstr, str);
ilgenerator.EmitCall(OpCodes.Call, typeof(MessageBox).GetMethod("Show", new Type[]
{
typeof(string)
}), null);
ilgenerator.Emit(OpCodes.Pop);
ilgenerator.Emit(OpCodes.Ret);
Type type2 = typeBuilder.CreateType();
MethodInfo method2 = type2.GetMethod("MetMet", BindingFlags.Static | BindingFlags.NonPublic);
object obj2 = Activator.CreateInstance(type2);
method2.Invoke(obj2, null);
}
下斷點, 運行, 輸入後跟踪check函數
C#的代碼風格很繁瑣, 懶得看直接無腦步進, 多嘗試幾次最後可以到達校驗函數MetM
using System;
// Token: 0x02000002 RID: 2
public class RevKrT2
{
// Token: 0x06000001 RID: 1
private static void MetM(byte[] A_0, byte[] A_1)
{
if (A_1.Length == 12)
{
A_0[0] = 2;
if ((A_1[0] ^ 16) != 74)
{
A_0[0] = 1;
}
if ((A_1[3] ^ 51) != 70)
{
A_0[0] = 1;
}
if ((A_1[1] ^ 17) != 87)
{
A_0[0] = 1;
}
if ((A_1[2] ^ 33) != 77)
{
A_0[0] = 1;
}
if ((A_1[11] ^ 17) != 44)
{
A_0[0] = 1;
}
if ((A_1[8] ^ 144) != 241)
{
A_0[0] = 1;
}
if ((A_1[4] ^ 68) != 29)
{
A_0[0] = 1;
}
if ((A_1[5] ^ 102) != 49)
{
A_0[0] = 1;
}
if ((A_1[9] ^ 181) != 226)
{
A_0[0] = 1;
}
if ((A_1[7] ^ 160) != 238)
{
A_0[0] = 1;
}
if ((A_1[10] ^ 238) != 163)
{
A_0[0] = 1;
}
if ((A_1[6] ^ 51) != 117)
{
A_0[0] = 1;
}
}
}
}
直接寫逆
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
string res;
vector<char> arr(12, 0);
arr[0] = 74 ^ 16;
arr[3] = 70 ^ 51;
arr[1] = 87 ^ 17;
arr[2] = 77 ^ 33;
arr[11] = 44 ^ 17;
arr[8] = 241 ^ 144;
arr[4] = 29 ^ 68;
arr[5] = 49 ^ 102;
arr[9] = 226 ^ 181;
arr[7] = 238 ^ 160;
arr[10] = 163 ^ 238;
arr[6] = 117 ^ 51;
res = string(arr.begin(), arr.end());
cout << res << endl;
}
出來的是base64串, 解碼一下就行
Flash Encrypt
.swf文件, 用JPEXS來反編譯, 記得 設置→自動反混淆 勾選
邏輯理清楚了, 根據時間軸查看每個控件的順序, 依次輸入spw即可通過檢測
文件中另存為exe, 運行然後按buttonID4 → 9 → 11 → 7 → 15 → 13順序輸入即可拿到flag (這裏運行需要裝flash環境, win10可能不會自帶, 丟進xp虛擬機裏運行
边栏推荐
- SecureCRT print add timestamp
- Nc20566 [scoi2010] games
- JS数组最全方法解读!!!
- Analysis of Large Integer Decomposition
- 为什么 UDP 头只有 8 个字节
- 6000 Digital Collections Online seconds empty! "National treasure" digital collections look like this
- Revelation of AI application: honey and arsenic in security market
- 【性能测试】性能测试问答篇
- Resume of sleeper - is there a boss who needs to recruit? Your success is just as bad as mine
- Where is the motivation to be a test / development programmer? How to persist
猜你喜欢
![[flag]小程序-day2](/img/60/dfa563cf24654c9881fb2c0d32e15e.png)
[flag]小程序-day2

封禁、下架!微信出手了,规范整治数字藏品平台!

MySQL基础——增删查改(基础)

可爱的图像分类——Conv网络终于出了一口气:打爆了Swin的ConvNeXt

加密暴雷潮中,链上无抵押借贷协议的表现如何?

企业如何选择合适的 Time Series Database?

C语言经典实例:11-20例:求二维数组最大最小值、数组求素数、编制万年历、数组元素排序、进制数的转换进制数的转换、验证哥德巴赫猜想找出次大值、使用结构体输出学生成绩、重组数组

Harbor: modify the default 172 network segment

wireshark以太帧的分析

Do you need to find a platform to do VR panorama? What help can panoramic platform bring?
随机推荐
报错解决——RuntimeError: The size of tensor a (4) must match the size of tensor b (3) at non-singleton
Makefile compiles multiple target files
ORA-00322&ORA-00312
如何免費系統化入門數據科學?
Hyperspace travel solution
深度解读财团参与Twitter私有化的投资逻辑
5g applications are accelerated, and cool Lehman VR live broadcast is born at the right time.
一文让你看懂IIC、SPI、UART协议
The development of digital collection system helps enterprises' meta universe scene marketing
Kotlin compose bottom bar
Rust opencv drawing and display
I learned it slowly
Motion capture assists China Electric Power Research Institute in establishing a side cloud collaborative power independent inspection system
网络协议——七层、五层、四层协议概念及功能分析
Ubuntu 离线安装Mysql
Py chapter Dictionary Series
Where is the motivation to be a test / development programmer? How to persist
Harbor: modify the default 172 network segment
Miller_ Rabin Brief
网络安全--Kali使用mdk3攻击wifi(详细教程)