Junk
利用int3进行父子进程进行通信来实现smc的操作
手动patch会遇到如下情况
第一会遇到调用函数情况,需要手动审查给call指令 让出位置
第二大多采用的都是循环加密 所以遇到一些call和循环结合,得手动修复一个for循环
第三得在审汇编和patch指令的时候意识到是tea算法,对有些不合理的进行自修改,例如ida识别的赋值寄存器,有时候明明没有进行低八位的交换,却在实际上是进行了的,这时候需要对加密算法有一些的熟悉
void __fastcall Courier(_DWORD *a1)
{
const void *v1; // rdx
DWORD64 v2; // rax
unsigned __int8 v3; // al
void *Rip; // rdx
HANDLE v5; // rcx
int *v6; // r8
__int64 Rsi_low; // rax
__int64 v8; // [rsp+30h] [rbp-48h] BYREF
unsigned __int8 v9; // [rsp+3Ah] [rbp-3Eh] BYREF
char Buffer; // [rsp+3Bh] [rbp-3Dh] BYREF
int v11; // [rsp+3Ch] [rbp-3Ch] BYREF
int v12; // [rsp+40h] [rbp-38h] BYREF
int v13; // [rsp+44h] [rbp-34h] BYREF
__int16 v14; // [rsp+4Ah] [rbp-2Eh] BYREF
int v15; // [rsp+4Ch] [rbp-2Ch] BYREF
SIZE_T NumberOfBytesRead; // [rsp+50h] [rbp-28h] BYREF
int v17; // [rsp+58h] [rbp-20h] BYREF
char v18; // [rsp+5Ch] [rbp-1Ch]
v15 = 0x2AF88348;
v14 = -16251;
v13 = -932245658;
v18 = 3;
v17 = -781119642;
v12 = -630255770;
v11 = -639692954;
if ( *a1 == -2147483645 )
{
if ( dword_1400040B0 )
{
Context.ContextFlags = 1048587;
GetThreadContext(hThread, &Context);
v1 = (const void *)Context.Rip--;
ReadProcessMemory(hProcess, v1, &Buffer, 1ui64, &NumberOfBytesRead);
switch ( Buffer )
{
case 1:
ReadProcessMemory(hProcess, (LPCVOID)(Context.Rip + 2), &v8, 1ui64, &NumberOfBytesRead);
ReadProcessMemory(hProcess, (LPCVOID)(Context.Rip + 3), &v9, 1ui64, &NumberOfBytesRead);
if ( (_BYTE)v8 == 3 )
{
v2 = Context.Rsp - v9; //sub rsp, 0x28
}
else
{
if ( (_BYTE)v8 != 2 )
exit(0);
v2 = Context.Rsp + v9;
}
Context.Rsp = v2;
Context.Rip += 4i64;
break;
case 4:
Context.Rcx = Context.Rsi; //mov rcx, rsi
Context.Rip += 3i64;
break;
case 5:
Rip = (void *)Context.Rip;
v5 = hProcess;
v6 = &v15;
goto LABEL_35;
case 6:
Context.Rdx = Context.Rsi; //mov rdx, rsi
Context.Rip += 3i64;
break;
case 7:
WriteProcessMemory(hProcess, (LPVOID)Context.Rip, &v14, 2ui64, &NumberOfBytesRead);
break;
case 8:
LODWORD(Context.Rdx) = 0x9E3779B9;
Context.Rip += 5i64;
break;
case 9:
LODWORD(Context.R11) = 32; //mov r11d, 0x20
Context.Rip += 6i64;
break;
case 10:
LODWORD(Context.Rax) = Context.Rsi;//mov eax, esi
Context.Rip += 2i64;
break;
case 11:
LODWORD(Context.Rbx) = Context.Rax; //mov ebx,eax
Context.Rip += 2i64;
break;
case 12:
Rsi_low = LODWORD(Context.Rsi);
goto LABEL_24;
case 13:
LODWORD(Context.Rbx) += 45; //add ebx ,0x2D
Context.Rip += 3i64;
break;
case 14:
Rsi_low = LODWORD(Context.Rdi); //xor ebx, edi
LABEL_24:
Context.Rbx ^= Rsi_low;
Context.Rip += 2i64; //xor ebx, esi
break;
case 15:
LODWORD(Context.Rcx) += LODWORD(Context.Rbx);
Context.Rip += 2i64;
break;
case 16:
LODWORD(Context.Rsi) = Context.Rcx; // mov esi, ecx
Context.Rip += 2i64;
break;
case 17:
LODWORD(Context.Rsi) += 67; //add esi, 0x43
Context.Rip += 3i64;
break;
case 18:
Context.Rdi ^= Context.Rsi; //xor edi, esi
Context.Rip += 2i64;
break;
case 19:
LODWORD(Context.Rsi) += 86;
Context.Rip += 3i64; //add esi,0x56
break;
case 20:
Context.Rsi ^= LODWORD(Context.Rdi); // xor esi, edi
Context.Rip += 2i64;
break;
case 21:
v3 = LOBYTE(Context.Rax) + 50;
goto LABEL_16;
case 22:
v3 = LOBYTE(Context.Rax) ^ 0x66;
LABEL_16:
v9 = v3;
LOBYTE(Context.Rax) = v3;
Context.Rip += 2i64;
break;
case 23:
Rip = (void *)Context.Rip;
v5 = hProcess;
v6 = &v13;
goto LABEL_35;
case 24:
WriteProcessMemory(hProcess, (LPVOID)Context.Rip, &v17, 5ui64, &NumberOfBytesRead);
break;
case 25:
Rip = (void *)Context.Rip;
v5 = hProcess;
v6 = &v12;
goto LABEL_35;
case 26:
Rip = (void *)Context.Rip;
v5 = hProcess;
v6 = &v11;
LABEL_35:
WriteProcessMemory(v5, Rip, v6, 4ui64, &NumberOfBytesRead); case 5:
Rip = (void *)Context.Rip;
v5 = hProcess;
v6 = &v15;
v15 = 0x2AF88348;
break;
case 27:
++Context.Rbx;
Context.Rip += 4i64;
break;
case 28:
Context.Rcx = Context.Rdi;
Context.Rip += 4i64;
break;
case 29:
v8 = Context.Rip + 2;
Context.Rsp -= 8i64;
WriteProcessMemory(hProcess, (LPVOID)Context.Rsp, &v8, 8ui64, &NumberOfBytesRead);
Context.Rip = (DWORD64)sub_140001950;
break;
case 30:
v8 = Context.Rip + 2;
Context.Rsp -= 8i64;
WriteProcessMemory(hProcess, (LPVOID)Context.Rsp, &v8, 8ui64, &NumberOfBytesRead);
Context.Rip = (DWORD64)qword_140001A50;
break;
default:
break;
}
SetThreadContext(hThread, &Context);
dwContinueStatus = 65537;
}
else
{
dword_1400040B0 = 1;
dwContinueStatus = 65537;
}
}
}
修复完的checkbox
#include <stdio.h>
#include <stdint.h>
void decrypt(uint32_t* v) {
uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;
uint32_t delta = 0x9e3779b9;
for (i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + 67) ^ (v0 + sum) ^ ((v0 >> 5) +86);
v0 -= ((v1 << 4) + 12) ^ (v1 + sum) ^ ((v1 >> 5) + 45);
sum -= delta;
}
v[0] = v0; v[1] = v1;
}
int main()
{
unsigned char enc[42] = {
0xF2, 0x7F, 0x09, 0x05, 0xD7, 0x77, 0x16, 0x91, 0x25, 0x01, 0x2E, 0xC5, 0x97, 0x26, 0x63, 0x82,
0x01, 0x40, 0x15, 0x2D, 0xFC, 0x53, 0xDB, 0xD3, 0xC4, 0xDB, 0x0A, 0x1F, 0x82, 0x1E, 0x99, 0x4E,
0xFE, 0x0C, 0x80, 0xB8, 0xA5, 0x61, 0x0E, 0x99, 0xDF, 0x39
};
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
for (int i = 0; i < 42; i++)
{
enc[i] = __ROR1__(enc[i], 5);
}
for (int i = 0; i < 42; i++)
{
enc[i] ^= 0x66;
enc[i] -= 50;
}
for (int i = 0; i < 9; i++)
{
if (i % 2 == 0)
{
decrypt((uint32_t*)enc + i);
}
}
puts((char*)enc);/*flag{be4e13b5-72cd-4eab-70ab-22eba6b4176f}*/
return 0;
}
标签:case,junk,LODWORD,Rip,break,复现,Context,网鼎杯,Rsi
From: https://www.cnblogs.com/Chis42/p/16644702.html