跟着大佬学RE(三)

crackMe

!isalnum(a1i)

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表) 函数好像也没什么用

并且这个题开了重定位

FlareOn4IgniteMe

GetInput 函数:

CheckInput:

sub_401000 函数返回一个 key 用于下面异或,该值可以静态分析,也可以动态调试,exe 没有开重定位。逻辑都很简单。

MRCTF2020Xor

ida:analyse failed

这个错一般是 ida 无法正确识别 函数参数个数函数调用约定 导致的。尤其是调用如 printf、scanf 这些参数个数可变的函数函数时,ida 会出现这样的错误

需要看 output window,通过 log 信息知道是哪句调用分析失败了,当然弹窗也给地址了

双击进去看看,按 F5 ,再回到 main 函数 可以 F5 了,如果还不行就要人工干预,将光标放在函数头的位置按 'Y' 强行修改参数个数或参数类型

然后就非常简单了

GKCTF2020BabyDriver

Windows 10 Driver x64

flag{} 中为 32 位小写。

那最后再写吧

WUSTCTF2020Cr0ssfun

藏在一个个函数里,主要想学学使用 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 

gBUUCTF re 2019红帽杯xx WP - 简书

相关推荐
白狐_798几秒前
408 数据结构|KMP做题方法:next、nextval和高频易错点
数据结构·算法
月华路3 分钟前
《模型不玄学》第20章 两种评估视角
人工智能·算法·机器学习
禹凕27 分钟前
快速幂算法详解与实战
python·算法
xxwl58531 分钟前
高斯消元法异或版
人工智能·算法·机器学习
sylviiiiiia36 分钟前
leetcode hot 100
python·算法·leetcode
OPEN-F1 小时前
ROS2系列教程:Gazebo插件(关节控制/IMU/激光雷达)
c++·python·数码相机·算法·机器人
luj_17681 小时前
虚实交融中的真实人物塑造
c语言·开发语言·网络·经验分享·算法
haolin123.2 小时前
STL vector底层揭秘:从构造到迭代器失效
开发语言·c++·算法
shehuiyuelaiyuehao2 小时前
算法37,位运算,两个整数之和(不用+符号)
算法
猎头南楼2 小时前
MFC 质量流量控制器中的控制算法设计与落地思考
人工智能·算法