BUUCTF-RE-0x05


title: BUUCTF-RE-0x05
date: 2021-06-06 21:14:44
tags:

BUUCTF刷题记录

期末了,都没办法在网上刷RE的题了。复习ing加油~~~~

[ACTF新生赛2020]rome

题目详情

BUUCTF-RE-0x05

下载下来

查壳

BUUCTF-RE-0x05

没壳,先放入IDA32。然后在F5之后,直接进入字符串搜索,发现正确的地方,然后跳转过去。

int func()
{
  int result; // eax
  int v1[4]; // [esp+14h] [ebp-44h]
  unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREF
  unsigned __int8 v3; // [esp+25h] [ebp-33h]
  unsigned __int8 v4; // [esp+26h] [ebp-32h]
  unsigned __int8 v5; // [esp+27h] [ebp-31h]
  unsigned __int8 v6; // [esp+28h] [ebp-30h]
  int v7; // [esp+29h] [ebp-2Fh]
  int v8; // [esp+2Dh] [ebp-2Bh]
  int v9; // [esp+31h] [ebp-27h]
  int v10; // [esp+35h] [ebp-23h]
  unsigned __int8 v11; // [esp+39h] [ebp-1Fh]
  char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREF

  strcpy(v12, "Qsw3sj_lz4_Ujw@l");
  printf("Please input:");
  scanf("%s", &v2);
  result = v2;
  if ( v2 == 'A' )
  {
    result = v3;
    if ( v3 == 'C' )
    {
      result = v4;
      if ( v4 == 'T' )
      {
        result = v5;
        if ( v5 == 'F' )
        {
          result = v6;
          if ( v6 == '{' )
          {
            result = v11;
            if ( v11 == '}' )
            {
              v1[0] = v7;
              v1[1] = v8;
              v1[2] = v9;
              v1[3] = v10;
              *(_DWORD *)&v12[17] = 0;
              while ( *(int *)&v12[17] <= 15 )
              {
                if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 64 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 'Z' )
                  *((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;
                if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 96 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 122 )
                  *((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;
                ++*(_DWORD *)&v12[17];
              }
              *(_DWORD *)&v12[17] = 0;
              while ( *(int *)&v12[17] <= 15 )
              {
                result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];
                if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )
                  return result;
                ++*(_DWORD *)&v12[17];
              }
              result = printf("You are correct!");
            }
          }
        }
      }
    }
  }
  return result;
}

然后粗略读下来还是读懂了,然后就是把这个简单的算法逆向应该就可以了。

flag

BUUCTF-RE-0x05

v12 ="Qsw3sj_lz4_Ujw@l"
v12list=list(v12)
v12l =[]
for i in range(len(v12)):
    v12l.append(ord(v12list[i]))
# v12l = [81,115,119,51,115,106,95,108,122,52,95,85,106,119,64,108]
flag = ''
for k in range(0,16):
    for i in range(0,127):
        z = i
        if i > 64 and i <= 90:
            i = (i-51)%26 + 65
        if i > 96 and i <= 122:
            i = (i-79)%26 + 97
        if(i == v12l[k]):
            flag += chr(z)

print("flag{"+flag+"}")
# flag{Cae3ar_th4_Gre@t}

flag{Cae3ar_th4_Gre@t}

BUUCTF-RE-0x05

[FlareOn4]login

题目

BUUCTF-RE-0x05

下载后解压后发现是个网页。

BUUCTF-RE-0x05

文本文档没有什么重要的信息。所以我们打开这个,用的是 sublimeText3 打开的,然后看见了这个简单的代码,所以就可以做出了。

login.html 源码

<!DOCTYPE Html />
<html>
    <head>
        <title>FLARE On 2017</title>
    </head>
    <body>
        <input type="text" name="flag" id="flag" value="Enter the flag" />
        <input type="button" id="prompt" value="Click to check the flag" />
        <script type="text/javascript">
            document.getElementById("prompt").onclick = function () {
                var flag = document.getElementById("flag").value;
                var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
               
                if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
                    alert("Correct flag!");
                } else {
                    alert("Incorrect flag, rot again");
                }
            }
        </script>
    </body>
</html>

BUUCTF-RE-0x05

分析

代码的意思是,将输入方框里面的内容进行替换,然后判断能否等于所比较的内容。而大概的方法是通过13位的替换的方法,只替换字母。

然后在网上可以找到叫做 rot13 的回转13位密码置换的方法。

于是就这个思路写简单的算法。

str ="PyvragFvqrYbtvafNerRnfl@syner-ba.pbz"
flag = ""

string="abcdefghijklmnopqrstuvwxyz"
string2=string.upper()
string+=string2
strlist = list(string)

for i in str:
    if i in string:
        temp = string.find(i)
        if(temp%26-13<0):
            temp+=13
        else:
            temp-=13
        flag += strlist[temp]
    else:
        temp=ord(i)
        flag+=i

print("flag{"+flag+"}")
# flag{ClientSideLoginsAreEasy@flare-on.com}

思路就是将每一个在另一个表中去寻找,然后如果求26的余减去13为负,说明原来的时候也是变过的,所以就不需要改变。

flag

flag:
flag{ClientSideLoginsAreEasy@flare-on.com}

小结

感觉这道题很有意思,很简单的一个算法。
像是一个凯撒加密位移了13的密码。

[GUET-CTF2019]re

描述

BUUCTF-RE-0x05

查壳

发现是upx的压缩壳,而且是elf文件,所以就用upx解压了。

BUUCTF-RE-0x05

下一步,拖入IDA进行分析一下。

进入主函数看看:

__int64 __fastcall sub_400E28(__int64 a1, int a2, int a3, int a4, int a5, int a6)
{
  int v6; // edx
  int v7; // ecx
  int v8; // er8
  int v9; // er9
  __int64 result; // rax
  __int64 v11; // [rsp+0h] [rbp-30h] BYREF
  unsigned __int64 v12; // [rsp+28h] [rbp-8h]

  v12 = __readfsqword(0x28u);
  sub_40F950((unsigned int)"input your flag:", a2, a3, a4, a5, a6, 0LL, 0LL, 0LL, 0LL);
  sub_40FA80((unsigned int)"%s", (unsigned int)&v11, v6, v7, v8, v9, v11);
  if ( (unsigned int)sub_4009AE(&v11) )
    sub_410350("Correct!");
  else
    sub_410350("Wrong!");
  result = 0LL;
  if ( __readfsqword(0x28u) != v12 )
    sub_443550();
  return result;
}

大致可以看出这个逆向挺简单,就是将输入的进行判断一下。

进入判断那个函数

(unsigned int)sub_4009AE(&v11)

_BOOL8 __fastcall sub_4009AE(char *a1)
{
  if ( 1629056 * *a1 != 166163712 )
    return 0LL;
  if ( 6771600 * a1[1] != 731332800 )
    return 0LL;
  if ( 3682944 * a1[2] != 357245568 )
    return 0LL;
  if ( 10431000 * a1[3] != 1074393000 )
    return 0LL;
  if ( 3977328 * a1[4] != 489211344 )
    return 0LL;
  if ( 5138336 * a1[5] != 518971936 )
    return 0LL;
  if ( 7532250 * a1[7] != 406741500 )
    return 0LL;
  if ( 5551632 * a1[8] != 294236496 )
    return 0LL;
  if ( 3409728 * a1[9] != 177305856 )
    return 0LL;
  if ( 13013670 * a1[10] != 650683500 )
    return 0LL;
  if ( 6088797 * a1[11] != 298351053 )
    return 0LL;
  if ( 7884663 * a1[12] != 386348487 )
    return 0LL;
  if ( 8944053 * a1[13] != 438258597 )
    return 0LL;
  if ( 5198490 * a1[14] != 249527520 )
    return 0LL;
  if ( 4544518 * a1[15] != 445362764 )
    return 0LL;
  if ( 3645600 * a1[17] != 174988800 )
    return 0LL;
  if ( 10115280 * a1[16] != 981182160 )
    return 0LL;
  if ( 9667504 * a1[18] != 493042704 )
    return 0LL;
  if ( 5364450 * a1[19] != 257493600 )
    return 0LL;
  if ( 13464540 * a1[20] != 767478780 )
    return 0LL;
  if ( 5488432 * a1[21] != 312840624 )
    return 0LL;
  if ( 14479500 * a1[22] != 1404511500 )
    return 0LL;
  if ( 6451830 * a1[23] != 316139670 )
    return 0LL;
  if ( 6252576 * a1[24] != 619005024 )
    return 0LL;
  if ( 7763364 * a1[25] != 372641472 )
    return 0LL;
  if ( 7327320 * a1[26] != 373693320 )
    return 0LL;
  if ( 8741520 * a1[27] != 498266640 )
    return 0LL;
  if ( 8871876 * a1[28] != 452465676 )
    return 0LL;
  if ( 4086720 * a1[29] != 208422720 )
    return 0LL;
  if ( 9374400 * a1[30] == 515592000 )
    return 5759124 * a1[31] == 719890500;
  return 0LL;
}

这个将每一个数值进行算数后进行比较。所以将这些数值取出来,然后逆向就行了。

不过发现少了a1[6] 第七个不见了。

逆向出来的代码:

# [GUET-CTF2019]re

list1 =[ 166163712,731332800,357245568,1074393000,489211344,518971936,406741500,294236496,177305856,
         650683500,298351053
         ,386348487,438258597,249527520,445362764,174988800,981182160,493042704,257493600, 767478780
         ,312840624, 1404511500 ,316139670,619005024, 372641472,373693320,498266640, 452465676,
         208422720,515592000,719890500 ]
list2 =[   1629056,6771600,3682944,10431000,3977328,5138336,7532250,5551632,3409728,13013670,6088797
           ,7884663,8944053,5198490,4544518,3645600,10115280,9667504,5364450,13464540,5488432,14479500,
        6451830,6252576,7763364,7327320,8741520,8871876,4086720,9374400,5759124 ]


flag=""
list =[]
print(len(list1),len(list2))
for i in range(0,len(list1)):
    # if i==6:
    #     temp='~'
    # else:
    temp=list1[i]/list2[i]
    temp = int(temp)
    list.append(temp)
    flag+=chr(temp)

print(list)
print(flag)
# flag{e65421110b0a3099a1c039337}

所以flag就是

flag{e?65421110b0a3099a1c039337}
然后就是一个一个试

BUUCTF-RE-0x05

看了一圈发现自己错的竟然是16和17位的位置换了。。。

所以改下原来的表。

改后flag

# [GUET-CTF2019]re

list1 =[ 166163712,731332800,357245568,1074393000,489211344,518971936,406741500,294236496,177305856,
         650683500,298351053 ,386348487,438258597,249527520,445362764,981182160,174988800,493042704,
         257493600, 767478780   ,312840624, 1404511500 ,316139670,619005024, 372641472,373693320,
         498266640, 452465676, 208422720,515592000,719890500 ]
list2 =[   1629056,6771600,3682944,10431000,3977328,5138336,7532250,5551632,3409728,13013670,6088797
           ,7884663,8944053,5198490,4544518,10115280,3645600,9667504,5364450,13464540,5488432,14479500,
        6451830,6252576,7763364,7327320,8741520,8871876,4086720,9374400,5759124 ]


flag=""
list =[]
print(len(list1),len(list2))
for i in range(0,len(list1)):
    # if i==6:
    #     temp='~'
    # else:
    temp=list1[i]/list2[i]
    temp = int(temp)
    list.append(temp)
    flag+=chr(temp)

print(list)
print(flag)
# flag{e165421110ba03099a1c039337}  # flag
# flag{e 65421110b0a3099a1c039337}
# flag{e 65421110ba03099a1c039337}  改后

BUUCTF-RE-0x05

Android模拟器检测常用方法

江城的程序员大叔

分类专栏: 你好,Android 文章标签: android android模拟器 防作弊 虚拟机 模拟器检测
版权
在Android开发过程中,防作弊一直是老生常谈的问题,而模拟器的检测往往是防作弊中的重要一环,接下来有关于模拟器的检测方法,和大家进行一个简单的分享。

1.传统的检测方法。

传统的检测方法主要是对模拟器的IMSI、IDS、默认文件等几个方面进行检测。

(1)默认号码:

private static String[] known_numbers = {"15555215554", "15555215556",
            "15555215558", "15555215560", "15555215562", "15555215564",
            "15555215566", "15555215568", "15555215570", "15555215572",
            "15555215574", "15555215576", "15555215578", "15555215580",
            "15555215582", "15555215584"};

(2)默认ID:

private static String[] known_device_ids = {"000000000000000"};

(3)默认IMSI:

private static String[] known_imsi_ids = {"310260000000000"};

(4)默认文件路径:

private static String[] known_files = {
            "/system/lib/libc_malloc_debug_qemu.so",
            "/sys/qemu_trace",
            "/system/bin/qemu-props"};

在得知了这些信息后,只需在运行时进行检测,如果检测结果和默认值吻合,那么检测设备便是模拟器。不过随着防反作弊技术的迭代,现在很多模拟器都可以改变这些值来逃避检测,所以上述传统方法在很多时候未曾达到开发者的预期效果。

2.基于模拟器cpu信息的检测。

成功率相较于传统方法,有了更高的成功率。

cpu信息检测主要是在cpu信息看看是否包含intel、amd等字段,很多模拟器目前对于cpu信息还无法进行模拟。

(1)读取cpu信息:

 public static String readCpuInfo() {
        String result = "";
        try {
            String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
            ProcessBuilder cmd = new ProcessBuilder(args);

​        Process process = cmd.start();
​        StringBuffer sb = new StringBuffer();
​        String readLine = "";
​        BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));
​        while ((readLine = responseReader.readLine()) != null) {
​            sb.append(readLine);
​        }
​        responseReader.close();
​        result = sb.toString().toLowerCase();
​    } catch (IOException ex) {
​    }
​    return result;
}

(2)进行判定:

String cpuInfo = readCpuInfo();
if ((cpuInfo.contains("intel") || cpuInfo.contains("amd"))) {return true;}

类似的还有

String[] blockList = "google_sdk,sdk,sdk_x86,vbox86p".split(",");

原理相同。

3.关键路径检测特定模拟器检测

前面2个方法在很大程度上已经可以鉴定出很多模拟器了,但是对于某些在反防作弊上同样热爱的模拟器,需要特定的检测方法。

bluestacks成功躲避了前两种检测方法,所以在这里给予其VIP的待遇。

以下是总结出来的一些bluestacks的关键路径:

 private static String[] known_bluestacks = {"/data/app/com.bluestacks.appmart-1.apk", "/data/app/com.bluestacks.BstCommandProcessor-1.apk",
            "/data/app/com.bluestacks.help-1.apk", "/data/app/com.bluestacks.home-1.apk", "/data/app/com.bluestacks.s2p-1.apk",
            "/data/app/com.bluestacks.searchapp-1.apk", "/data/bluestacks.prop", "/data/data/com.androVM.vmconfig",
            "/data/data/com.bluestacks.accelerometerui", "/data/data/com.bluestacks.appfinder", "/data/data/com.bluestacks.appmart",
            "/data/data/com.bluestacks.appsettings", "/data/data/com.bluestacks.BstCommandProcessor", "/data/data/com.bluestacks.bstfolder",
            "/data/data/com.bluestacks.help", "/data/data/com.bluestacks.home", "/data/data/com.bluestacks.s2p", "/data/data/com.bluestacks.searchapp",
            "/data/data/com.bluestacks.settings", "/data/data/com.bluestacks.setup", "/data/data/com.bluestacks.spotlight", "/mnt/prebundledapps/bluestacks.prop.orig"
    };

检测方法:

public static boolean checkBlueStacksFiles() {
        for (int i = 0; i < known_bluestacks.length; i++) {
            String file_name = known_bluestacks[i];
            File qemu_file = new File(file_name);
            if (qemu_file.exists()) {
                FkLog.e("Result : Find BlueStacks Files!");
                return true;
            }
        }
        FkLog.e("Result : Not Find BlueStacks Files!");
        return false;
    }

这种基于关键路径的检测,便可以成功的检测出bluestacks。

4.模拟器检测新思路

模拟器检测与模拟器反检测都在不断的更新迭代中,无法确保哪一种方法会永垂不朽,在这里分享下新的思路。

电池信息检测

可以从电池的温度和电量等信息入手,检测温度在使用过程中是否一直保持不变、或者是电量一直是固定值并且不是百分之百等等。

亲测可以鉴别出genymotion、bluestacks等主流模拟器。

5.写在最后

其实很多时候在检测模拟器的过程中,都不是只使用某一种固定的方法,一来需要具体问题具体分析,二来也需要用多种方法来综合检测。言而总之,有了十八般武艺才能见招拆招。

ps:如有错误或需要补充的地方,请各位多多指正~

————————————————
版权声明:本文为CSDN博主「江城的程序员大叔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_33150417/article/details/51320228

ISCC2021-Analysis

题目描述

BUUCTF-RE-0x05

然后下载后IDA去查看。

查壳

发现没有壳,真好。。哈哈哈哈

BUUCTF-RE-0x05

使用IDA32打开看看。

然后分析如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str[3]; // [esp+11h] [ebp-97h] BYREF
  _BYTE v5[57]; // [esp+14h] [ebp-94h] BYREF
  int v6; // [esp+4Dh] [ebp-5Bh]
  char v7[64]; // [esp+51h] [ebp-57h] BYREF
  char v8[7]; // [esp+91h] [ebp-17h] BYREF
  int v9; // [esp+98h] [ebp-10h]
  int i; // [esp+9Ch] [ebp-Ch]

  __main();
  v6 = 0;
  memset(v5, 0, 4 * (((Str - v5 + 64) & 0xFFFFFFFC) >> 2));
  Str[0] = 67;
  Str[1] = 223;
  Str[2] = 20;
  v5[0] = 3;
  v5[1] = 13;
  v5[2] = 44;
  v5[3] = 9;
  v5[4] = 1;
  v5[5] = 23;
  v5[6] = 23;
  v5[7] = 8;
  v5[8] = 252;
  v5[9] = 43;
  v5[10] = 250;
  v5[11] = 20;
  v5[12] = 23;
  v5[13] = 249;
  v5[14] = 37;
  v5[15] = 245;
  v5[16] = 34;
  v5[17] = 61;
  v5[18] = 206;
  v5[19] = 24;
  v5[20] = 22;
  v5[21] = 10;
  qmemcpy(v8, "REVERSE", sizeof(v8));           // v8 = REVERSE
  v9 = strlen(Str);                             // v9 = 25
  printf(Format);
  scanf("%s", v7);
  mix(v7, v8, v9);
  for ( i = 0; i < v9; ++i )
  {
    if ( v7[i] != Str[i] )                      // v7[i] == Str[i]
    {
      puts(Buffer);                             // 错误
      return 0;
    }
  }
  puts(aFlag);                                  // 正确
  return 0;
}

mix(v7, v8, v9);

int __cdecl mix(char *v7, char *v8, int v9)
{
  char v3; // dl
  int result; // eax
  char v5; // [esp+14h] [ebp-24h]
  int n; // [esp+18h] [ebp-20h]
  int m; // [esp+1Ch] [ebp-1Ch]
  int l; // [esp+20h] [ebp-18h]
  size_t k; // [esp+24h] [ebp-14h]
  int j; // [esp+28h] [ebp-10h]
  int i; // [esp+2Ch] [ebp-Ch]
                                                // 目的:逆向出v7
  for ( i = 0; i < v9; ++i )                    // v8[7] = RESERVE
                                                // v9 疑似25
    v7[i] -= 64;
  for ( j = 0; j < v9; ++j )
    v7[j] -= v7[j + 1];
  for ( k = 0; k < strlen(v8); ++k )
    v8[k] %= 64;                                // 后面的v8都要改变
  for ( l = 0; l < v9; ++l )
    v7[l] += v8[l % 7];
  for ( m = 0; v9 / 2 > m; ++m )                // 翻转
  {
    v5 = v7[m];
    v7[m] = v7[v9 - m - 1];
    v7[v9 - m - 1] = v5;
  }
  for ( n = 0; ; ++n )
  {
    result = n;
    if ( n >= v9 )
      break;
    if ( (v8[n % 7] & 1) != 0 )                 // v8[i] != 0  -> v7[i] +2
                                                // v8[i] == 0  -> v7[i] +1
      v3 = v7[n] + 2;                           // v7[i] +2
    else
      v3 = v7[n] + 1;
    v7[n] = v3;
  }
  return result;
}

re

然后写出自己的逆向算法

v7A=[67,-33,20,3,13,44,9,1,23,23,8,-4,43,-6,20,23,-7,37,-11,34,61,-50,24,22,10]
# print(len(v7A))
# v7A = [67,223,20,3,13,44,9,1,23,23,8,252,43,250,20,23,249,37,245,34,61,206,24,22,10]
# v8 = "RESERVE"
# v8l = [R,E,S,E,R,V,E]
v8s = "REVERSE"
v8l = list(v8s)
print(v8l)
v8 =[]
print("v81=")
for i in range(len(v8l)):
    v8.append(ord(v8l[i])%64);
    print(ord(v8l[i]), end=',')

print("v8=",end='')
print(v8)

for i in range(0,25):
    if ((v8[i % 7] & 1) != 0):
        # v3 = v7A[i] - 2;
        v7A[i] -= 2 ;
    else:
        # v3 = v7A[i] - 1;
        v7A[i] -= 1;

print(v7A) ;
v7A.reverse()
v9 = len(v7A)
# for i in range(0,int(v9/2)):
#     temp = v7A[i];
#     v7A[i] = v7A[v9-i-1]
#     v7A[v9-i-1]  = temp ;
# print("v7A=",end='')
print(v7A)
for i in range(0,25):
    v7A[i] -= v8[i % 7];

for i in range(23,-1,-1):
    v7A[i] += v7A[i+1]
flag=""
print(v7A)
for i in range(len(v7A)):
    v7A[i] += 64
    flag+=chr(v7A[i])
print(v7A)
# [75, 85, 70, 67, 123, 82, 71, 88, 71, 85, 83, 69, 95, 75, 85, 97, 81, 79, 84, 95, 74, 67, 84, 71, 125]

# a="ISCC"
# 73,83,67,67,
print(flag)
# ISCC{REVERSE_IS_NOT_HARD}

Youngter-drive

文件

BUUCTF-RE-0x05

开始以为是按照题目的提示会有什么解题的方法,然后没有发现。

下载下来是一个EXE的 PE 文件。下载

查壳

传统的查壳步骤。

BUUCTF-RE-0x05

BUUCTF-RE-0x05

然后准备使用OD和x64手脱,但是发现好像有点问题。脱不了,因为缺少一个运行库。初步怀疑是文件下载后丢失的。所以就使用UPX脱壳机完成脱壳。

BUUCTF-RE-0x05

看见是32位的软件,所以就不动态调试了。直接IDA32然后打开。

分析

找了一会儿,然后找到主函数

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  void *v3; // ecx
  HANDLE v5; // [esp+D0h] [ebp-14h]
  HANDLE hObject; // [esp+DCh] [ebp-8h]

  sub_4110FF(v3);
  ::hObject = CreateMutexW(0, 0, 0);
  j_strcpy(Destination, Source);
  hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);
  v5 = CreateThread(0, 0, sub_41119F, 0, 0, 0);
  CloseHandle(hObject);
  CloseHandle(v5);
  while ( dword_418008 != -1 )
    ;
  sub_411190();
  CloseHandle(::hObject);
  return 0;
}

然后发现整个主要是在第一个函数和后面的两个函数来进行处理。

然后有两个线程来进行调用。

BUUCTF-RE-0x05

然后发现只有29个的样子。

网上的方法

flagpart = 'TOiZiZtOrYaToUwPnToBsOaOapsyS'
flagrange = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'
flag = ''
for i in range(len(flagpart)):
    if i % 2 == 0:
        flag += flagpart[i]
    else:
        if flagpart[i].isupper():
            flag += chr(flagrange.find(flagpart[i]) + 96)
        else:
            flag += chr(flagrange.find(flagpart[i]) + 38)
print("flag{"+flag+"}")
print(len(flag))

然后就继续看WP发现是随便一位都可以,然后看见是E

BUUCTF-RE-0x05

WP

详解

总结

了解了多线程的实际运用了,然后对于多线程的解法有点懂了。

END~

上一篇:PHP & “Data” URL scheme(转)


下一篇:Data Url生成工具之HTML5 FileReader实现