首页
社区
课程
招聘
[原创] 看雪 2022 KCTF 秋季赛 第十题 两袖清风
发表于: 2022-12-11 05:16 15280

[原创] 看雪 2022 KCTF 秋季赛 第十题 两袖清风

2022-12-11 05:16
15280

一道奇奇怪怪的题,直到最后也理解不了考察点是什么,希望出题人可以开源出来看看。

(自己从周五晚上开始认真看题,爆肝一整天直到周六晚上才找到答案。10个小时出一血是真的快,应该是完全没有被外围逻辑分散精力)

主要逻辑都在 sub_140007660 里。策略还是先标记出函数,然后动态调试验证。

重要函数:

关键逻辑:

0x1400080DA:

这里限制了输入的长度上限是205

0x1400081E8:

检查了输入长度最小为89。
特别的,由于这个printf输出的是no,所以这个if块后面的部分完全不需要看(从0x14000824B开始到0x140008C91,在F5伪代码中占了足足一半)(最开始没有先注意到这个printf,浪费了一些时间。这些代码似乎都是内联进来的析构函数)

0x140008C91:

截取输入的前85个字节,按照十六进制解析初始化为一个大数,作为bn_powmod的指数参与运算(底数和模是上面的两个常量),计算结果再转回十六进制、hexdecode,暂时存入come_from_input_first_85_bytes变量中。
这里同时初始化了v197,后面会用到。
截取输入索引85开始的4个字节。由于LABEL_275输出no,所以不能跳转过去,这4个字节要求是数字。

后面是一个看起来很复杂的三重循环(其实到最后也没理清楚),但是值得关注的只有中间一部分:
0x140009178:

0x140009288

由于 0x140009288 的判断存在,所以 stdstring_concat 必须要被调用到,所以要从上面的break跳出来,而不能goto LABEL_201。
v114 == v115 + v111 && v114 == (char)v215 + v111 && v114 == v115 + SLOBYTE(v214[0]) 推出 v115 == v215v111 == SLOBYTE(v214[0]);同时反向可验证只要满足这两个等式,if的条件一定会通过。

动态调试发现这4个数分别就是输入索引85开始的4个字节,约束是第1等于第3,第2等于第4。随手试,"0000" 不行,但 "0101" 可以(不知道具体原因)。

0x1400092D1:

这段主要是 aes_cbc_decrypt 解密一段固定常量。算法是 AES 256,密钥 key 是 come_from_input_first_85_bytes(v126),iv 是 v197(v125)。
(v125和v126在IDA中被标记为VALUE MAY BE UNDEFINED,需要看汇编+动态调试确认)
iv: v197在很早以前就计算出来了,值是固定的"ABCDEF0123456789"。
key:come_from_input_first_85_bytes 原本是模幂的计算结果的hexdecode,但是经过上面的三重循环后,其前面被附加了输入索引85开始的4个字节。无论如何,key是由输入的前89个字节完全确定的。跟进aes内部的key expansion,由 0x140001167 处的循环可以判断出 key 的长度为 32,即 AES256。

0x1400094F6:

这里取了输入索引89以后的所有字节

0x140009545:

如果索引89以后的的字节不为空(即输入长度大于89),则会进入这个if判断,核心部分是检查输入的全部字节为[0-9A-Z],同时在索引89之后不能有两个连续的'0'。

0x14000979E:

这里是把v134写入最开始分配出来的内存中。动态调试可以发现开头4个字符固定是"kctf",后面输入索引89以后的字节的hexdecode。同时也向偏移220和240的两个地方写入了 "Try again!\n" 和 "good!\n" 两个字符串。

0x1400098D0:

0x14000758C:(在 sub_140007410 内部)

sub_14000AF4E里面是很多syscall,没看懂是什么原理,但是从对它的调用 sub_14000AF4E((__int64)hObject, RtlFillMemory, (__int64)&a2[v12], 1i64, *a3, v19) 来看,应该等价于调用第二个参数指示的函数。
根据上下文,这两块逻辑应该是创建一个线程,动态调试发现前面aes解密出来的shellcode被写入一块内存中。

0x14000992C:

sub_14000AF4E再次出现了,所以之前解密出的shellcode会被当做函数(注意,函数是需要ret的,后面会利用这一点),在ResumeThread时执行。
(由于shellcode是根据输入的前89个字节解密的,所以如果随便输入,动态调试到这里时程序会因为非法指令而异常退出。)
暂时修改rip跳过这里,先调试下一段代码。

0x1400099CF:

最后一块逻辑是经典的利用uuid隐藏shellcode:再次分配了一段内存,然后UuidFromStringA从很多uuid常量中解出shellcode,作为第一个参数调用EnumSystemLocalesA(第一个参数会被当做函数在EnumSystemLocalesA中回调)
回顾前面对偏移220和240位置的写入,似乎只要 v154[4] * v154[4] + 5 * v154[8] * v154[8] * v154[8] - 2 * v154[4] * v154[6] * v154[6] + 3 == 0 就会成功,但是,稍微爆破一下 v154[4], v154[6], v154[8] 这三个字节,就会发现是无解的。

所以,EnumSystemLocalesA调用的shellcode内部肯定做了一些事情。
开头是自修改,运行完自修改(到偏移0x23的位置)再dump。

结合动态调试,整体逻辑还是相对清晰的。查找"kctf"找内存段,BaseAddress即为主要函数sub_140007660开始分配的内存区域,前4个字节是"kctf",后面跟着的是输入索引89以后的字节hexdecode的内容,然后是一块空白区域、一串01,以及220偏移处的"Try again!\n"和240偏移处的"good!\n"。
如果通过了shellcode末尾的检查,则会把220偏移处的"Try again!\n"修改为"good!\n",所以真正的检查逻辑就是这段shellcode。

这段shellcode整体逻辑如下(不太好描述,直接看代码吧。不过上面ida输出的伪代码可以复制出来编译,也能本地测试):
整块内存前4个字节是"kctf",然后是输入索引89以后的字节hexdecode的内容(这块内容的第一个字节是长度;后面的字节会hexencode,奇偶相间分别构成两个序列,每个序列的相邻两个值相差要求为1,且第二个序列要以0开头,同时两个序列至少有一个是以0或9结尾)。后面是两个10*10的区域,对每个区域,前面的两个序列分别是横纵坐标,检查要求所有坐标的位置都是0;以及,第一个区域的全部100个字节都要是0(第二个区域无此要求)。

反调试:

代码中有大量反调试,并且会修改 antidebug(0x140079CD0)这个全局变量指向的内存,而且位置会向后递增。

0x1400076C2

这是 sub_140007660 开头的一段代码,lpBaseAddress_ 是最后shellcode检查的内存段,动态调试看到的01序列在这里初始化;另外,antidebug也落在了两个10*10的区域的范围内。

反调试很多,大部分都能在调试器中忽略并继续,但这一处有些特殊:
0x140007375 (在 check_if_is_digit 中)

在x64dbg调试时如果忽略这里的异常,程序并不会调用TopLevelExceptionFilter,而是两次异常后直接退出,但是自己写代码测试发现如果不附加调试器就完全正常。
猜测原因是这里的异常由RaiseException api主动引发,异常的派生可能是内核处理?而UnhandledException在有调试器附加的时候会被调试器接收到,即使调试器选择忽略,但已经影响了系统的处理逻辑?(不太确定,熟悉Windows的朋友可以留言解释一下)

大部分反调试如果触发,会在 antidebug++ 相应的位置赋值为非0值,这会直接影响最后shellcode的检查。
但是有一处例外,在前面检查输入字符是否为[0-9A-Z]的位置(0x140009545的if块内部的0x1400096B3位置),对于每个符合要求的字符都会在 antidebug++ 指向的位置多赋值一个 0,这意味着如果输入较长,会被赋值更多的0,有利于最后的shellcode检查。

分析的差不多了,现在是时候寻找程序的正确输入了

首先是最后shellcode检查,受限于输入最长不能超过205个字符,所以 0x1400096B3 antidebug++ 赋值0的位置不会超过 0xDC (220) 的位置,而这里的位置保存在 "Try again!\n" 非 0 字符,也即中间的空白区域小于两个 10*10 区域(大概只有一百几十个字节),所以需要让索引尽可能小。
两个10*10 区域共用一套索引,第一个区域100个字节都要是0,则第二个区域只有开头的几十个字节才能是0。区域索引是二维坐标,所以横坐标要尽可能小。

横纵坐标各自的序列相邻位置差值必须是1,且第一个纵坐标必须是0,最后一个横坐标和纵坐标至少有1个是0或9;另外由于坐标值直接来源于原始输入,也受到原始输入不能存在相邻的0的限制。

基于以上限制,考虑先把最后一个纵坐标限定为9,那么一个最短的可行坐标序列如下:

对应到原始输入索引89之后的字节即为 "10011203140516071809"

实测发现,空白区域还是少了几个字节。根据之前的分析,增大2字节输入长度会使得 antidebug++ 赋值2个0,但是在此处只增加1个字节,合计增加了1个0的空白区域,所以适当增加长度,例如:

对应到原始输入索引89之后的字节即为 "1021120312031203140516071809",可以通过shellcode的检查。显然这里的构造方法不唯一。

还剩下最后一个问题没有解决:前面0x14000992C代码块会在ResumeThread(hThread)时异常退出。这里实际上是由于根据输入前89字节解密出的shellcode函数存在非法指令,所以需要控制解密出来的字节。
既然shellcode是需要ret的函数,最简单的方式是控制ret指令(C3)在第一个字节,就可以不触发异常的通过这里。
无法反推到原始输入(因为要逆推aes key,再解离散对数,都是不可能的任务),但是由于只需要控制解密后的第一个字节,所以可以直接爆破

得到一个输入 "123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF01243"

把三部分拼起来

得到一个可行的答案:

通过验证:

(按照上面的分析,显然题目存在无数的解,所以非常好奇题目的源码逻辑是怎样的)

 
 
 
sub_140006DE0:scanf_s
sub_1400007F0:printf
 
sub140006FD0:str_xor,主要是异或解密一些常量 
sub_140007180:hexdecode
sub_1400072B0:check_if_is_digit,检查一个std::string的字符是否全部是数字
sub_1400093C0:aes_cbc_decrypt,AES256 CBC 模式解密
 
std::string相关:
sub_140006060:stdstring_substr,取子串
sub_1400015F0:stdstring_init_from_cstr,构造函数(从char *构造)
sub_140006230,stdstring_copy,拷贝构造函数
sub_1400015C0:str_destructor,析构函数
sub_140006130:stdstring_cstr,返回内部缓冲区指针
sub_140006660:stdstring_concat,连接两个字符串
sub_140006140:stdstring_get,取索引位置的字符
 
大数运算:
sub_140001EE0:bn_init_from_str,从16进制大端序列的std::string初始化(bn内部是小端序)
sub_140004D70:bn_to_str,转换为16进制大端序的std::string
sub_1400042D0:bn_powmod,模幂运算
sub_140006DE0:scanf_s
sub_1400007F0:printf
 
sub140006FD0:str_xor,主要是异或解密一些常量 
sub_140007180:hexdecode
sub_1400072B0:check_if_is_digit,检查一个std::string的字符是否全部是数字
sub_1400093C0:aes_cbc_decrypt,AES256 CBC 模式解密
 
std::string相关:
sub_140006060:stdstring_substr,取子串
sub_1400015F0:stdstring_init_from_cstr,构造函数(从char *构造)
sub_140006230,stdstring_copy,拷贝构造函数
sub_1400015C0:str_destructor,析构函数
sub_140006130:stdstring_cstr,返回内部缓冲区指针
sub_140006660:stdstring_concat,连接两个字符串
sub_140006140:stdstring_get,取索引位置的字符
 
大数运算:
sub_140001EE0:bn_init_from_str,从16进制大端序列的std::string初始化(bn内部是小端序)
sub_140004D70:bn_to_str,转换为16进制大端序的std::string
sub_1400042D0:bn_powmod,模幂运算
 
 
scanf_s("%s", v32, a1.s.size);    // sub_140006DE0
scanf_s("%s", v32, a1.s.size);    // sub_140006DE0
 
if ( inputlen < 0x59 )                        // 0x59, 89
{
  v46 = (char *)&v179.s;
  if ( v179.s.capacity >= 0x10ui64 )
    v46 = (char *)v179.s.s;
  str_xor(v46, v179.s.size, "Y?j0?");
  v47 = (const char *)&v179.s;
  if ( v179.s.capacity >= 0x10ui64 )
    v47 = (const char *)v179.s.s;
  printf(v47);                                // "no!\n"  0x140008238
  ...
if ( inputlen < 0x59 )                        // 0x59, 89
{
  v46 = (char *)&v179.s;
  if ( v179.s.capacity >= 0x10ui64 )
    v46 = (char *)v179.s.s;
  str_xor(v46, v179.s.size, "Y?j0?");
  v47 = (const char *)&v179.s;
  if ( v179.s.capacity >= 0x10ui64 )
    v47 = (const char *)v179.s.s;
  printf(v47);                                // "no!\n"  0x140008238
  ...
 
stdstring_substr(&a1, &input_first_85_bytes, 0i64, 85ui64);
stdstring_init_from_cstr(
  &v208,
  "B20446102D1C343D0575674CA28EBC0419BCFE4D75682C2AC81C9502454650BDDAEF6968AF269B54C182");
stdstring_init_from_cstr(
  &v189,
  "4F62187B5F6590C6CFF0FBDBBEBDAF60AA861BD2F66F8F7FFD57A66AE50DB7D2FFFFFFFFFFFFFFFFFFFFF");
bn_init_from_str(&v207, &v189);
str_destructor(&v189);
stdstring_init_from_cstr(&v189, "11");
bn_init_from_str(&v211, &v189);
str_destructor(&v189);
v95 = stdstring_cstr(&input_first_85_bytes);
stdstring_init_from_cstr(&v210, v95);
bn_init_from_str(&v206, &v210);
str_destructor(&v210);
bn_init_from_str(&v205, &v208);
bn_powmod(&v205, &v204, &v206, &v207);
bn_to_str(&v204, &v195);
v96 = stdstring_cstr(&v195);
hexdecode(v96, v97);
v98 = stdstring_cstr(&v195);
v100 = str_xor(v98, v99, "Y?j0?");
stdstring_init_from_cstr(&come_from_input_first_85_bytes, v100);
origin_size_of_come_from_input_first_85_bytes = come_from_input_first_85_bytes.s.size;
stdstring_init_from_cstr(&v197, byte_1400710A0);
stdstring_substr(&a1, &from_input_4_bytes_at_85, 85ui64, 4ui64);
sub_140009ED0(&v180, from_input_4_bytes_at_85.s.size);
*(_QWORD *)v214 = &v189;
v215 = &v210;
v101 = sub_14000A140(&from_input_4_bytes_at_85, &v189);
v102 = sub_14000A1E0(&from_input_4_bytes_at_85, &v210);
sub_14000A270(&v180, v102, v101);
v103 = stdstring_cstr(&v197);
str_xor(v103, v197.s.size, "Y?j0?");          // "ABCDEF0123456789"
v187 = (unsigned __int64)&v189;
v104 = stdstring_copy(&v189, &from_input_4_bytes_at_85);
if ( !check_if_is_digit(v104) || from_input_4_bytes_at_85.s.size != 4 )
  goto LABEL_275;
ii = 0i64;
start = v180.v.start;
...
stdstring_substr(&a1, &input_first_85_bytes, 0i64, 85ui64);
stdstring_init_from_cstr(
  &v208,
  "B20446102D1C343D0575674CA28EBC0419BCFE4D75682C2AC81C9502454650BDDAEF6968AF269B54C182");
stdstring_init_from_cstr(
  &v189,
  "4F62187B5F6590C6CFF0FBDBBEBDAF60AA861BD2F66F8F7FFD57A66AE50DB7D2FFFFFFFFFFFFFFFFFFFFF");
bn_init_from_str(&v207, &v189);
str_destructor(&v189);
stdstring_init_from_cstr(&v189, "11");
bn_init_from_str(&v211, &v189);
str_destructor(&v189);
v95 = stdstring_cstr(&input_first_85_bytes);
stdstring_init_from_cstr(&v210, v95);
bn_init_from_str(&v206, &v210);
str_destructor(&v210);
bn_init_from_str(&v205, &v208);
bn_powmod(&v205, &v204, &v206, &v207);
bn_to_str(&v204, &v195);
v96 = stdstring_cstr(&v195);
hexdecode(v96, v97);
v98 = stdstring_cstr(&v195);
v100 = str_xor(v98, v99, "Y?j0?");
stdstring_init_from_cstr(&come_from_input_first_85_bytes, v100);
origin_size_of_come_from_input_first_85_bytes = come_from_input_first_85_bytes.s.size;
stdstring_init_from_cstr(&v197, byte_1400710A0);
stdstring_substr(&a1, &from_input_4_bytes_at_85, 85ui64, 4ui64);
sub_140009ED0(&v180, from_input_4_bytes_at_85.s.size);
*(_QWORD *)v214 = &v189;
v215 = &v210;
v101 = sub_14000A140(&from_input_4_bytes_at_85, &v189);
v102 = sub_14000A1E0(&from_input_4_bytes_at_85, &v210);
sub_14000A270(&v180, v102, v101);
v103 = stdstring_cstr(&v197);
str_xor(v103, v197.s.size, "Y?j0?");          // "ABCDEF0123456789"
v187 = (unsigned __int64)&v189;
v104 = stdstring_copy(&v189, &from_input_4_bytes_at_85);
if ( !check_if_is_digit(v104) || from_input_4_bytes_at_85.s.size != 4 )
  goto LABEL_275;
ii = 0i64;
start = v180.v.start;
...
 
  if ( v112 != kk && v112 != jj && v113 != ii )
  {
    v114 = (char)v215 + SLOBYTE(v214[0]);
    v115 = start[v113];
    if ( v114 == v115 + v111 && v114 == (char)v215 + v111 && v114 == v115 + SLOBYTE(v214[0]) )
      break;
  }
  ++v112;
  ++v113;
  if ( v112 >= 4 )
    goto LABEL_201;
}
kk = 5;
ii_i = 5i64;
v110 = 5i64;
jj = 5;
v187 = 5i64;
ii = 5i64;
v116 = stdstring_concat(&v189, &from_input_4_bytes_at_85, &come_from_input_first_85_bytes);
strnode_assign(&come_from_input_first_85_bytes, v116);
str_destructor(&v189);
start = v180.v.start;
  if ( v112 != kk && v112 != jj && v113 != ii )
  {
    v114 = (char)v215 + SLOBYTE(v214[0]);
    v115 = start[v113];
    if ( v114 == v115 + v111 && v114 == (char)v215 + v111 && v114 == v115 + SLOBYTE(v214[0]) )
      break;
  }
  ++v112;
  ++v113;
  if ( v112 >= 4 )
    goto LABEL_201;
}
kk = 5;
ii_i = 5i64;
v110 = 5i64;
jj = 5;
v187 = 5i64;
ii = 5i64;
v116 = stdstring_concat(&v189, &from_input_4_bytes_at_85, &come_from_input_first_85_bytes);
strnode_assign(&come_from_input_first_85_bytes, v116);
str_destructor(&v189);
start = v180.v.start;
if ( come_from_input_first_85_bytes.s.size > (unsigned __int64)origin_size_of_come_from_input_first_85_bytes )
...
if ( come_from_input_first_85_bytes.s.size > (unsigned __int64)origin_size_of_come_from_input_first_85_bytes )
...
 
 
v214[0] = 8;
v214[1] = 14;
stdstring_resize(&stru_140079DB0, 0xDC0ui64);
v118 = stdstring_cstr(&stru_140079DB0);
memcpy(v118, Src, 0xDC0ui64);
v119 = stdstring_cstr(&stru_140079DB0);
str_xor(v119, stru_140079DB0.s.size, "?x}da");
src_size = (unsigned __int64)stru_140079DB0.s.size >> 1;
v121 = stdstring_cstr(&stru_140079DB0);
hexdecode(v121, src_size);
v122 = stdstring_cstr(&come_from_input_first_85_bytes);
str_xor(v122 + 4, v123, "Y?j0?");
stdstring_cstr(&v197);                      // iv
stdstring_cstr(&come_from_input_first_85_bytes);// key
from_src = stdstring_cstr(&stru_140079DB0);
v127 = aes_cbc_decrypt(v214, from_src, src_size, v126, v125);
stdstring_init_from_cstr(&v196, v127);
v128 = stdstring_cstr(&v185);
str_xor(v128, v185.s.size, "!?>d*");
v129 = stdstring_cstr(&v181);
str_xor(v129, v181.s.size, "?x)da");
v130 = stdstring_cstr(&v181);
v131 = stdstring_cstr(&v185);
ModuleHandleA = GetModuleHandleA(v131);     // kernel32.dll
RtlFillMemory = (__int64)GetProcAddress(ModuleHandleA, v130);// RtlFillMemory
if ( !RtlFillMemory )
  goto LABEL_274;
virtualalloc_region_1 = (char *)VirtualAllocEx(hProcess, 0i64, v196.s.size, 0x3000u, 0x40u);
v134 = (char *)malloc2(a1.s.size);
v135 = stdstring_cstr(&v186);
str_xor(v135, v186.s.size, "*s>0?");
v136 = stdstring_cstr(&v186);               // "kctf"
v137 = v134 - v136;
v214[0] = 8;
v214[1] = 14;
stdstring_resize(&stru_140079DB0, 0xDC0ui64);
v118 = stdstring_cstr(&stru_140079DB0);
memcpy(v118, Src, 0xDC0ui64);
v119 = stdstring_cstr(&stru_140079DB0);
str_xor(v119, stru_140079DB0.s.size, "?x}da");
src_size = (unsigned __int64)stru_140079DB0.s.size >> 1;
v121 = stdstring_cstr(&stru_140079DB0);
hexdecode(v121, src_size);
v122 = stdstring_cstr(&come_from_input_first_85_bytes);
str_xor(v122 + 4, v123, "Y?j0?");
stdstring_cstr(&v197);                      // iv
stdstring_cstr(&come_from_input_first_85_bytes);// key
from_src = stdstring_cstr(&stru_140079DB0);
v127 = aes_cbc_decrypt(v214, from_src, src_size, v126, v125);
stdstring_init_from_cstr(&v196, v127);
v128 = stdstring_cstr(&v185);
str_xor(v128, v185.s.size, "!?>d*");
v129 = stdstring_cstr(&v181);
str_xor(v129, v181.s.size, "?x)da");
v130 = stdstring_cstr(&v181);
v131 = stdstring_cstr(&v185);
ModuleHandleA = GetModuleHandleA(v131);     // kernel32.dll
RtlFillMemory = (__int64)GetProcAddress(ModuleHandleA, v130);// RtlFillMemory
if ( !RtlFillMemory )
  goto LABEL_274;
virtualalloc_region_1 = (char *)VirtualAllocEx(hProcess, 0i64, v196.s.size, 0x3000u, 0x40u);
v134 = (char *)malloc2(a1.s.size);
v135 = stdstring_cstr(&v186);
str_xor(v135, v186.s.size, "*s>0?");
v136 = stdstring_cstr(&v186);               // "kctf"
v137 = v134 - v136;
 
v139 = stdstring_substr(&a1, &v189, 89ui64, a1.s.size);
v140 = stdstring_cstr(v139);
v141 = v134 - 1;
do
  ++v141;
while ( *v141 );
strcpy(v141, v140);
v139 = stdstring_substr(&a1, &v189, 89ui64, a1.s.size);
v140 = stdstring_cstr(v139);
v141 = v134 - 1;
do
  ++v141;
while ( *v141 );
strcpy(v141, v140);
 
    if ( a1.s.size )
    {
        ...
        if ( v145[i_2] >= 'a' )
        {
          if ( *stdstring_get(&a1, j_2) <= 'z' )
          {
            v146 = antidebug;
            *(_BYTE *)antidebug = 1;
            goto LABEL_237;
          }
          size_2 = a1.s.size;
        ...
        if ( (*(char *)(i_2 + v147) < '0' || *stdstring_get(&a1, j_2) > '9')
          && (*stdstring_get(&a1, j_2) < 'A' || *stdstring_get(&a1, j_2) > 'Z') )
        {
          v146 = antidebug;
          *(_BYTE *)antidebug = 2;
        }
        else
        {
          v146 = antidebug;
          *(_BYTE *)antidebug = 0;    //
        }
LABEL_237:
        antidebug = v146 + 1;
        if ( j_2 > 89 && *stdstring_get(&a1, j_2) == '0' && *stdstring_get(&a1, j_2 - 1i64) == '0' )
        {
          v148 = stdstring_cstr(&v179);
          str_xor(v148, v179.s.size, "Y?j0?");
          v149 = stdstring_cstr(&v179);
          printf(v149);                         // "no!\n"
          str_destructor(&v196);
          goto LABEL_276;
    if ( a1.s.size )
    {
        ...
        if ( v145[i_2] >= 'a' )
        {
          if ( *stdstring_get(&a1, j_2) <= 'z' )
          {
            v146 = antidebug;
            *(_BYTE *)antidebug = 1;
            goto LABEL_237;
          }
          size_2 = a1.s.size;
        ...
        if ( (*(char *)(i_2 + v147) < '0' || *stdstring_get(&a1, j_2) > '9')
          && (*stdstring_get(&a1, j_2) < 'A' || *stdstring_get(&a1, j_2) > 'Z') )
        {
          v146 = antidebug;
          *(_BYTE *)antidebug = 2;
        }
        else
        {
          v146 = antidebug;
          *(_BYTE *)antidebug = 0;    //
        }
LABEL_237:
        antidebug = v146 + 1;
        if ( j_2 > 89 && *stdstring_get(&a1, j_2) == '0' && *stdstring_get(&a1, j_2 - 1i64) == '0' )
        {
          v148 = stdstring_cstr(&v179);
          str_xor(v148, v179.s.size, "Y?j0?");
          v149 = stdstring_cstr(&v179);
          printf(v149);                         // "no!\n"
          str_destructor(&v196);
          goto LABEL_276;
 
TickCount64 = GetTickCount64();
v153 = (int)v150 + 5;
v154 = (char *)lpBaseAddress;
v155 = (int)hProcess;
WriteProcessMemory(hProcess, lpBaseAddress, v134, v153, (SIZE_T *)NumberOfBytesWritten);
v156 = (char *)&try_again.s;
if ( try_again.s.capacity >= 0x10ui64 )
  v156 = (char *)try_again.s.s;
str_xor(v156, try_again.s.size, "Y?j0?");
v157 = &try_again.s;
if ( try_again.s.capacity >= 0x10ui64 )
  v157 = (const void *)try_again.s.s;
*(_QWORD *)v214 = v154 + 220;
memcpy(v154 + 220, v157, try_again.s.size);    // "Try again!\n"
v158 = (char *)&good.s;
if ( good.s.capacity >= 0x10ui64 )
  v158 = (char *)good.s.s;
str_xor(v158, good.s.size, "Y?j0?");
v159 = &good.s;
if ( good.s.capacity >= 0x10ui64 )
  v159 = (const void *)good.s.s;
v215 = (struct strnode *)(v154 + 240);
memcpy(v154 + 240, v159, good.s.size);    // "good!\n"
shellcode_1 = (unsigned __int8 *)&v196.s;
if ( v196.s.capacity >= 0x10ui64 )
  shellcode_1 = (unsigned __int8 *)v196.s.s;
TickCount64 = GetTickCount64();
v153 = (int)v150 + 5;
v154 = (char *)lpBaseAddress;
v155 = (int)hProcess;
WriteProcessMemory(hProcess, lpBaseAddress, v134, v153, (SIZE_T *)NumberOfBytesWritten);
v156 = (char *)&try_again.s;
if ( try_again.s.capacity >= 0x10ui64 )
  v156 = (char *)try_again.s.s;
str_xor(v156, try_again.s.size, "Y?j0?");
v157 = &try_again.s;
if ( try_again.s.capacity >= 0x10ui64 )
  v157 = (const void *)try_again.s.s;
*(_QWORD *)v214 = v154 + 220;
memcpy(v154 + 220, v157, try_again.s.size);    // "Try again!\n"
v158 = (char *)&good.s;
if ( good.s.capacity >= 0x10ui64 )
  v158 = (char *)good.s.s;
str_xor(v158, good.s.size, "Y?j0?");
v159 = &good.s;
if ( good.s.capacity >= 0x10ui64 )
  v159 = (const void *)good.s.s;
v215 = (struct strnode *)(v154 + 240);
memcpy(v154 + 240, v159, good.s.size);    // "good!\n"
shellcode_1 = (unsigned __int8 *)&v196.s;
if ( v196.s.capacity >= 0x10ui64 )
  shellcode_1 = (unsigned __int8 *)v196.s.s;
 
if ( (unsigned int)sub_140007410(v155, virtualalloc_region_1, shellcode_1, LODWORD(v196.s.size) + 1)
  || (v176 = 0i64,
      v175 = 0i64,
      v174 = 0i64,
      v173 = 0i64,
      v172 = 1,
      (unsigned int)sub_14000B629((int)&hThread, 0x1FFFFF, 0, v155, (int)ExitThread, 0)) )
if ( (unsigned int)sub_140007410(v155, virtualalloc_region_1, shellcode_1, LODWORD(v196.s.size) + 1)
  || (v176 = 0i64,
      v175 = 0i64,
      v174 = 0i64,
      v173 = 0i64,
      v172 = 1,
      (unsigned int)sub_14000B629((int)&hThread, 0x1FFFFF, 0, v155, (int)ExitThread, 0)) )
  if ( !(unsigned int)sub_14000B629((int)&hObject, 0x1FFFFF, 0, a4, (int)ExitThread, 0) )
  {
    if ( !r9d0 )
    {
LABEL_15:
      ResumeThread(hObject);
      WaitForSingleObject(hObject, 0xFFFFFFFF);
      CloseHandle(hObject);
      return 0i64;
    }
    while ( !(unsigned int)sub_14000AF4E((__int64)hObject, RtlFillMemory, (__int64)&a2[v12], 1i64, *a3, v19) )
    {
      ++v12;
      ++a3;
      if ( v12 >= r9d0 )
        goto LABEL_15;
  if ( !(unsigned int)sub_14000B629((int)&hObject, 0x1FFFFF, 0, a4, (int)ExitThread, 0) )
  {
    if ( !r9d0 )
    {
LABEL_15:
      ResumeThread(hObject);
      WaitForSingleObject(hObject, 0xFFFFFFFF);
      CloseHandle(hObject);
      return 0i64;
    }
    while ( !(unsigned int)sub_14000AF4E((__int64)hObject, RtlFillMemory, (__int64)&a2[v12], 1i64, *a3, v19) )
    {
      ++v12;
      ++a3;
      if ( v12 >= r9d0 )
        goto LABEL_15;
 
sub_14000AF4E((__int64)hThread, (__int64)virtualalloc_region_1, 0i64, 0i64, 0, v171[0]);
v161 = (int)(GetTickCount64() - TickCount64) < 6000;
v162 = (_BYTE *)antidebug;
if ( !v161 )
{
  *(_BYTE *)antidebug = 9;
  antidebug = (__int64)++v162;
}
if ( debugger_present )
{
  *v162 = 6;
  antidebug = (__int64)(v162 + 1);
}
ResumeThread(hThread);
WaitForSingleObject(hThread, 0xFFFFFFFF);
CloseHandle(hThread);
if ( (unsigned int)sub_140006E40() != 0x478E )
sub_14000AF4E((__int64)hThread, (__int64)virtualalloc_region_1, 0i64, 0i64, 0, v171[0]);
v161 = (int)(GetTickCount64() - TickCount64) < 6000;
v162 = (_BYTE *)antidebug;
if ( !v161 )
{
  *(_BYTE *)antidebug = 9;
  antidebug = (__int64)++v162;
}
if ( debugger_present )
{
  *v162 = 6;
  antidebug = (__int64)(v162 + 1);
}
ResumeThread(hThread);
WaitForSingleObject(hThread, 0xFFFFFFFF);
CloseHandle(hThread);
if ( (unsigned int)sub_140006E40() != 0x478E )
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-12-11 05:24 被mb_mgodlfyn编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//