crackMe
!isalnum(a1[i])
string.isalnum()
是 python 中检查字符串是否全是字母或者数字,是返回true,否则false
刷新文件流缓冲区
应该和 flag 没有什么关系,继续往下看
嗯,我把所有 jz 改成了 jnz ,不对是直接 nop 掉 那个 if 语句
nop掉了,F5 显示代码过大,已经改那个 MAX_FUNSIZE 了啊!
只能先不改,看的时候注意一下分析吧
得到 v17:dbappsec
接下来就是要得到 byte_416050 数组
找一个比较合适的位置(有特殊(xor,add,sub之类的)指令位置)下断点
得到 ecx 每次循环的值:
0x7e,0x98,0xc9,0x95,0x10,0x6d,0xf3,0x67 就八个
得到的 byte 数组不对,啊!
都是用 OD 调的,我也去算了(用的ida)
撕,用的 x32dbg 调的,隐不隐藏调试器都得到了正确数组
那那个反调试是搞什么?只是防止静态分析吗?
python
#include <bits/stdc++.h>
using namespace std;
int a[] = {0x2A, 0xD7, 0x92, 0xE9, 0x53, 0xE2, 0xC4, 0xCD};
string s = "dbappsec";
int main() {
for (int i = 0; i < 8; i++) {
int num = (int)s[i];
int ans = num ^ (int)a[i];
cout << hex << ans;
}
return 0;
}
中间那个 Encode(生成Rc4表) 函数好像也没什么用
并且这个题开了重定位
[FlareOn4]IgniteMe
GetInput 函数:
CheckInput:
sub_401000 函数返回一个 key 用于下面异或,该值可以静态分析,也可以动态调试,exe 没有开重定位。逻辑都很简单。
[MRCTF2020]Xor
ida:analyse failed
这个错一般是 ida 无法正确识别 函数参数个数 或 函数调用约定 导致的。尤其是调用如 printf、scanf 这些参数个数可变的函数函数时,ida 会出现这样的错误
需要看 output window,通过 log 信息知道是哪句调用分析失败了,当然弹窗也给地址了
双击进去看看,按 F5 ,再回到 main 函数 可以 F5 了,如果还不行就要人工干预,将光标放在函数头的位置按 'Y' 强行修改参数个数或参数类型
然后就非常简单了
[GKCTF2020]BabyDriver
Windows 10 Driver x64
flag{} 中为 32 位小写。
那最后再写吧
[WUSTCTF2020]Cr0ssfun
藏在一个个函数里,主要想学学使用 sublime 的正则替换功能
ctrl+n 新建文件
嗯,抽时间学一下正则表达式
[2019红帽杯]xx
主体逻辑都在 main 函数里了
中间一大坨不知道在干嘛
只能倒着看了,硬着头皮啃
python
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rax
__int128 *v5; // rax
__int64 v6; // r11
__int128 *v7; // r14
int v8; // edi
__int128 *v9; // rsi
char v10; // r10
int v11; // edx
__int64 v12; // r8
unsigned __int64 v13; // rcx
__int64 v14; // rcx
unsigned __int64 v15; // rax
unsigned __int64 i; // rax
__int64 v17; // rax
size_t v18; // rsi
_BYTE *v19; // rbx
_BYTE *v20; // r9
int v21; // r11d
char *v22; // r8
__int64 v23; // rcx
char v24; // al
__int64 v25; // r9
__int64 v26; // rdx
__int64 v27; // rax
size_t Size; // [rsp+20h] [rbp-48h] BYREF
__int128 v30; // [rsp+28h] [rbp-40h] BYREF
int v31; // [rsp+38h] [rbp-30h]
int v32; // [rsp+3Ch] [rbp-2Ch]
int Code[4]; // [rsp+40h] [rbp-28h] BYREF
int v34; // [rsp+50h] [rbp-18h]
*(_OWORD *)Code = 0i64;
v34 = 0;
scanf(std::cin, argv, Code);
v3 = -1i64;
v4 = -1i64;
do
++v4;
while ( *((_BYTE *)Code + v4) ); // strlen(Code)=19
if ( v4 != 19 )
{
print(std::cout, "error\n");
_exit((int)Code);
}
v5 = (__int128 *)operator new(5ui64);
v6 = *(_QWORD *)&::Code; // qwertyuiopasdfghjklzxcvbnm1234567890
v7 = v5;
v8 = 0;
v9 = v5;
do
{
v10 = *((_BYTE *)v9 + (char *)Code - (char *)v5);
v11 = 0;
*(_BYTE *)v9 = v10;
v12 = 0i64;
v13 = -1i64;
do
++v13;
while ( *(_BYTE *)(v6 + v13) );
if ( v13 )
{
do
{
if ( v10 == *(_BYTE *)(v6 + v12) )
break;
++v11;
++v12;
}
while ( v11 < v13 );
}
v14 = -1i64;
do
++v14;
while ( *(_BYTE *)(v6 + v14) );
if ( v11 == v14 )
_exit(v6);
v9 = (__int128 *)((char *)v9 + 1);
}
while ( (char *)v9 - (char *)v5 < 4 );
*((_BYTE *)v5 + 4) = 0;
do
++v3;
while ( *((_BYTE *)Code + v3) );
v15 = 0i64;
v30 = *v7;
while ( *((_BYTE *)&v30 + v15) )
{
if ( !*((_BYTE *)&v30 + v15 + 1) )
{
++v15;
break;
}
if ( !*((_BYTE *)&v30 + v15 + 2) )
{
v15 += 2i64;
break;
}
if ( !*((_BYTE *)&v30 + v15 + 3) )
{
v15 += 3i64;
break;
}
v15 += 4i64;
if ( v15 >= 0x10 )
break;
}
for ( i = v15 + 1; i < 0x10; ++i )
*((_BYTE *)&v30 + i) = 0;
v17 = sub_140001AB0(Code, v3, &v30, &Size);
v18 = Size;
v19 = (_BYTE *)v17;
v20 = operator new(Size);
v21 = 1;
*v20 = v19[2];
v22 = v20 + 1;
v20[1] = *v19;
v20[2] = v19[3];
v20[3] = v19[1];
v20[4] = v19[6];
v20[5] = v19[4];
v20[6] = v19[7];
v20[7] = v19[5];
v20[8] = v19[10];
v20[9] = v19[8];
v20[10] = v19[11];
v20[11] = v19[9];
v20[12] = v19[14];
v20[13] = v19[12];
v20[14] = v19[15];
v20[15] = v19[13];
v20[16] = v19[18];
v20[17] = v19[16];
v20[18] = v19[19];
v20[19] = v19[17];
v20[20] = v19[22];
v20[21] = v19[20];
v20[22] = v19[23];
for ( v20[23] = v19[21]; v21 < v18; ++v22 )
{
v23 = 0i64;
if ( v21 / 3 > 0 )
{
v24 = *v22;
do
{
v24 ^= v20[v23++];
*v22 = v24;
}
while ( v23 < v21 / 3 );
}
++v21;
}
*(_QWORD *)&v30 = 0xC0953A7C6B40BCCEui64;
v25 = v20 - (_BYTE *)&v30;
*((_QWORD *)&v30 + 1) = 0x3502F79120209BEFi64;
v26 = 0i64;
v31 = -939386845;
v32 = -95004953;
do
{
if ( *((_BYTE *)&v30 + v26) != *((_BYTE *)&v30 + v26 + v25) )
_exit(v8 * v8);
++v8;
++v26;
}
while ( v26 < 24 );
v27 = print(std::cout, "You win!");
std::ostream::operator<<(v27, sub_1400017F0);
return 0;
}
python
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "encode.h"
int main()
{
int i,j,data[] = { 188, 165, 206, 64, 244, 178, 178, 231, 169, 18, 157, 18, 174, 16, 200, 91, 61, 215, 6, 29, 220, 112, 248, 220 };
for (i = 1; i <= 6; i++)//导出加密的数据,将其转换为十六进制并用小端序来表示
{
printf("0x");
for (j = i * 4 - 1; j > (i - 1) * 4 - 1; j--)
printf("%x", data[j]);
printf(",");
}
printf("\n0x");
int key[] = { 'f','l','a','g' };//导出密钥,将其转换为十六进制并用小端序来表示
for (i = 3; i >= 0; i--)
printf("%x", key[i]);
printf(",");
for (i = 0; i < 3; i++)//密钥为4个32位的数,1个字符4bit,4个字符为32bit,还差3个32bit的数
printf("0x0,");
}
//0x40cea5bc,0xe7b2b2f4,0x129d12a9,0x5bc810ae,0x1d6d73d,0xdcf870dc,
//0x67616c66,0x0,0x0,0x0,
感觉自己写脚本能力还是不行,只能先 copy 师傅的了,之后还是要多练。
python
data0 = "CEBC406B7C3A95C0EF9B202091F70235231802C8E75656FA"
data=[]
for i in range(0,len(data0),2):
data.append(int((data0[i]+data0[i+1]),16)) #十六进制字符串变成数据
print(data)
for i in range(len(data)-1,-1,-1):
for j in range(i//3):
data[i]^=data[j]
order=[2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]#还原顺序
enc=[1]*24
for i in range(24):
enc[order[i]]=data[i]
print(enc)
# [206, 188, 64, 107, 124, 58, 149, 192, 239, 155, 32, 32, 145, 247, 2, 53, 35, 24, 2, 200, 231, 86, 86, 250]
# [188, 165, 206, 64, 244, 178, 178, 231, 169, 18, 157, 18, 174, 16, 200, 91, 61, 215, 6, 29, 220, 112, 248, 220]
python
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "encode.h"
int main()
{
#if 0
uint32_t enc[6] = { (unsigned int)0x40cea5bc,(unsigned int)0xe7b2b2f4,(unsigned int)0x129d12a9,(unsigned int)0x5bc810ae,(unsigned int)0x1d06d73d,(unsigned int)0xdcf870dc };
int n = -6;
uint32_t const key[4] = { (unsigned int)0x67616c66,(unsigned int)0x0,(unsigned int)0x0,(unsigned int)0x0 };
btea(enc, n, key);
for (int i = 0; i < 6; i++)
printf("%x", enc[i]);
#endif
char string[] = "67616c665858437b646e615f742b2b5f7d6165";
int i = 1,j=0;
for (;i<6;i++)
{
for (j = 0; j < 8; j += 2)
{
if (j == 0 && i == 5)
continue;
printf("%c%c", string[i * 8 - j - 2], string[i * 8 - j - 1]);
}
}
}
//666c61677b4358585f616e645f2b2b7465617d