跟着大佬学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 - 简书

相关推荐
工业胶粘剂技术1 小时前
单组分高温环氧结构胶 K-EP280 完整技术参数与工程选型分析
算法·制造
小欣加油2 小时前
Leetcode31 下一个排列
数据结构·c++·算法·leetcode·职场和发展
_日拱一卒2 小时前
LeetCode:39组合总和
java·算法·leetcode·职场和发展
无限进步_2 小时前
【Linux】进程状态、僵尸与孤儿、进程调度
linux·运维·服务器·开发语言·数据结构·算法
郝学胜-神的一滴2 小时前
力扣 662 :二叉树最大宽度
java·数据结构·c++·python·算法·leetcode·职场和发展
2301_764441332 小时前
基于Stackelberg博弈的分散式库存模型
python·算法·数学建模
qq 13740186112 小时前
医用无菌屏障系统加速老化标准解读:ASTM F1980-2016 全解析
人工智能·算法·加速老化·包装测试·astm·医疗器械包装·无菌屏障系统
wayz112 小时前
Overlap:SLOPE(线性回归斜率)技术指标详解
算法·金融·数据分析·回归·线性回归·量化交易·特征工程
点云兔子2 小时前
舱口检测:从点云到矩形定位的射线投影算法
opencv·算法·点云·舱口检测
小欣加油2 小时前
leetcode169 多数元素
数据结构·c++·算法·leetcode·职场和发展