IsDebugger Present
原理
反调试,该API查询PEB结构中的IsDebugger标志位, 未调试返回0,调试状态返回1。
绕过
nop指令
jnz和jz
jnz在结果不为0时跳转,jz在结果为0时跳转
1 2 3 4 5 6 7 8 sub_4019F4 ( ){ return ISDebuggerPresent; } if (!sub_4019F4){ puts(); }
这个时候如果处于调试状态,返回1,不会执行put,这时候只需要去汇编指令处把jnz改为jz,重新汇编后会变成
1 2 3 4 5 6 7 8 sub_4019F4 ( ){ return ISDebuggerPresent; } if (sub_4019F4){ puts(); }
3.Attach to process
1 2 3 sub_4019F4() printf("%d" ,n) scanf("%d" ,&m )
可以先让程序运行,这时候已经步过了反调试函数,然后Attach to process就可以调试了
4.修改EIP:jump、call、ret指令
多线程
函数介绍
1 2 3 1 CreateThread 创建线程2 CloseHandle 关闭线程3 WaitForSingleObject() 实现线程转换
2.题目——Youngter drive
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int __cdecl main_0(int argc , const char ** argv , const char ** envp ) { HANDLE v4; HANDLE hObject; ((void (*)(void))sub_4110FF)() ; ::hObject = CreateMutexW(0, 0, 0) ; j_strcpy(Destination, &Source) ; hObject = CreateThread(0, 0, StartAddress, 0, 0, 0) ; v4 = CreateThread(0, 0, sub_41119F , 0, 0, 0) ; CloseHandle(hObject ) ; CloseHandle(v4 ) ; while ( dword_418008 != -1 ) ; sub_411190() ; CloseHandle(::hObject ) ; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 void __stdcall StartAddress_0(int a1 ) { while ( 1 ) { WaitForSingleObject(hObject , 0xFFFFFFFF) ; if ( dword_418008 > -1 ) { sub_41112C(&Source, dword_418008 ) ; --dword_418008; Sleep(0x64u) ; } ReleaseMutex(hObject ) ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 void __stdcall sub_411B10(int a1 ) { while ( 1 ) { WaitForSingleObject(hObject , 0xFFFFFFFF) ; if ( dword_418008 > -1 ) { Sleep(0x64u) ; --dword_418008; } ReleaseMutex(hObject ) ; } }
实际上就是每隔两位对数组元素做一次处理
Z3
基础
1 2 3 4 5 6 7 8 9 10 11 12 13 1 声明整数x = Int ('x' )2 声明实数x = Real ('x' )3 声明布尔类型x = Bool ('x' )1 创建solver 求解器 例:s = Solver () 2 添加约束条件 例:s.add (x +y ==10 ) 3 检查solver 中的约束是否满足 例:s.check () 4 利用model ()输出运算结果 例:s.model ()
2.题目——Universe_final_answer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 __int64 __fastcall main(int a1, char **a2, char **a3) { char v4[32 ] ; char input[104 ] ; unsigned __int64 v6; v6 = __readfsqword(0x28u) ; __printf_chk(1LL, "Please give me the key string:" , a3 ) ; scanf("%s" , input); if ( sub_860(input ) ) { sub_C50(input , v4 ) ; __printf_chk(1LL, "Judgement pass! flag is actf{%s_%s}\n" , input ) ; } else { puts("False key!" ); } return 0L L; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 bool __fastcall sub_860(char *input) { int v1; // ecx int v2; // esi int v3; // edx int v4; // er9 int v5; // er11 int v6; // ebp int v7; // ebx int v8; // er8 int v9; // er10 bool result; // al int v11; // [rsp+0h] [rbp-38h] v1 = input[1]; v2 = *input; v3 = input[2]; v4 = input[3]; v5 = input[4]; v6 = input[6]; v7 = input[5]; v8 = input[7]; v9 = input[8]; result = 0; if ( -85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 ) { v11 = input[9]; if ( 30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400 && -103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 << 6) - 120 * v9 == -10283 && 71 * v6 + (v7 << 7) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855 && 5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944 && -54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222 && -83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258 && 81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559 && 101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308 ) { result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697; } } return result; }
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from z3 import*s =Solver()v1 =Int('v1 ')v2 =Int('v2 ')v3 =Int('v3 ')v4 =Int('v4 ')v5 =Int('v5 ')v6 =Int('v6 ')v7 =Int('v7 ')v8 =Int('v8 ')v9 =Int('v9 ')v11 =Int('v11 ')s .add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 )s .add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613 )s .add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (v6 *64 ) - 120 * v9 == -10283 )s .add(71 * v6 + (v7 *128 ) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855 )s .add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944 )s .add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222 )s .add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258 )s .add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559 )s .add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308 )s .add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697 )if s.check()==sat: result =s.model() print (result)
这里的移位操作不能被识别,需要手动转换。
其实这道题带了个简单的混淆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 unsigned __int64 __fastcall sub_C50(const char *a1, _BYTE *a2) { size_t v4; // rax unsigned int v5; // edx int v6; // edi int v7; // ecx __int64 v8; // r8 __int128 *v9; // rsi unsigned int v10; // ecx int v11; // eax int v12; // edi int v13; // edx int v14; // eax _BYTE *v15; // rsi _BYTE *v16; // rcx _BYTE *v17; // r8 int *i; // rax unsigned __int64 result; // rax __int128 v20[2]; // [rsp+0h] [rbp-48h] BYREF __int64 v21; // [rsp+20h] [rbp-28h] unsigned __int64 v22; // [rsp+28h] [rbp-20h] v22 = __readfsqword(0x28u); v20[0] = 0LL; v21 = 0LL; v20[1] = 0LL; v4 = strlen(a1); v5 = 0; v6 = 9; while ( v5 < v4 ) { v7 = a1[v5++]; v6 ^= v7; } if ( v6 ) { v8 = 0LL; v9 = v20; while ( 1 ) { v9 = (__int128 *)((char *)v9 + 4); v10 = v8 + 1; v11 = v6 / 10; v12 = v6 % 10; *((_DWORD *)v9 - 1) = v12; LOBYTE(v13) = v12; v6 = v11; if ( !v11 ) break; v8 = v10; } v14 = v8 - 1; v15 = a2; v16 = &a2[v10]; v17 = &a2[v8]; for ( i = (int *)v20 + v14; ; --i ) { *v15 = v13 + 48; if ( v17 == v15 ) break; v13 = *i; ++v15; } } else { v16 = a2; } result = __readfsqword(0x28u) ^ v22; *v16 = 0; return result; }
这里面的函数没有对输入进行处理,所以不用管
修改二进制文件汇编指令
1.题目——Overlong
运行程序,得到
1 2 I never broke the encoding:
1 2 3 4 5 6 7 8 9 10 11 int __stdcall start (int a1, int a2, int a3, int a4){ CHAR Text [128 ]; // [esp+0 h] [ebp-84 h] BYREF int v6; // [esp+80 h] [ebp-4 h] v6 = sub_401160(Text , &unk_402008, 28 ); Text [v6] = 0 ; MessageBoxA(0 , Text , Caption, 0 ); return 0 ; }
这里只取出了TEXT的前28位,而程序运行后的输出长度正好是28,加上题目overlong提示和:结尾,猜测部分长度没显示
所以需要修改二进制文件汇编指令
1 2 3 4 5 6 7 .text: 004011C0 push ebp .text: 004011C1 mov ebp , esp .text: 004011C3 sub esp , 84h .text: 004011C9 push 1Ch .text: 004011CB push offset unk_402008.text: 004011D0 lea eax , [ebp +Text]
1c对应28,所以需要将1c改大
1、ida修改–> 点击菜单项“Edit”–“Patch program”–“Assemble” --> 点击菜单项“Edit”–“Patch program”–“Apply patches to input file”,在弹出的对话框中点击OK按钮,则成功完成指令修改。
点击确认按钮时,可能会弹出无法写入对话框,只需去除该文件的只读属性,再次执行第三步即可。
2、OD修改–>根据汇编指令定位–>右键–>二进制–>编辑 ,其他的可以直接修改指令,但是这里修改之后后面的汇编代码全变了,虽然不知道为啥。
3、winhex修改–>定位——先去ida的patch byte找到push 1c对应6A 1C 68 08 20 40 00 8D 85 7C FF FF FF 50 E8 84–>去winhex修改1c,然后重新保存运行
RSA
1、题目——Signin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 __int64 __fastcall main(int a1, char **a2, char **a3) { char v4[16 ] ; char v5[16 ] ; char v6[16 ] ; char v7[16 ] ; char v8[112 ] ; char v9[1000 ] ; unsigned __int64 v10; v10 = __readfsqword(0x28u) ; puts("[sign in]" ); printf("[input your flag]: " ); __isoc99_scanf("%99s" , v8 ) ; sub_96A(v8 , v9 ) ; __gmpz_init_set_str(v7 , "ad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35" , 16LL) ; __gmpz_init_set_str(v6 , v9 , 16LL) ; __gmpz_init_set_str(v4 , "103461035900816914121390101299049044413950405173712170434161686539878160984549" , 10LL) ; __gmpz_init_set_str(v5 , "65537" , 10LL) ; __gmpz_powm(v6 , v6 , v5 , v4 ) ; if ( (unsigned int )__gmpz_cmp(v6 , v7 ) ) puts("GG!" ); else puts("TTTTTTTTTTql!" ); return 0L L; }
看到65537,加上查了__gmpz_powm()函数,也相当于__mpz_powm()函数,可以判断这是rsa加密
1 2 3 void mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp , const mpz_t mod ) [Function ] Set rop to base^exp mod mod .
其实就是计算 base 的 exp 次方,并对 mod 取模,最后将结果写入 rop 中
剩下的就是解出p、q,然后写脚本了
1 2 3 4 5 6 7 8 C = M ^ E mod N C 是密文,M 是明文,E 是公钥(E 和 φ( N ) 互为质数),N 是公共模数(质数 P 、Q 相乘得到N ),MOD 就是模运算M = C ^ D mod N 求D :E * D % φ( N ) = 1 φ( N ) = ( P - 1 ) ( Q - 1 )
2、rsa
题目给出了公钥和flag.enc文件
公钥和密钥生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 4.1 求N 我们准备两个很小对质数, p = 17 q = 19 N = p * q = 323 4.2 求L L = lcm (p -1 , q -1 )= lcm ( 16 ,18 ) = 144 144 为16 和18 对最小公倍数4.3 求E 求E 必须要满足2 个条件:1 < E < L ,gcd (E ,L )= 1 即1 < E < 144 ,gcd (E ,144 ) = 1 #gcd ,最大公因数 E 和144 互为质数,5 显然满足上述2 个条件故E = 5 此时公钥= ( E ,N )= (5 ,323 ) 4.4 求D 求D 也必须满足2 个条件:1 < D < L ,E *D mod L = 1 即1 < D < 144 ,5 * D mod 144 = 1 显然当D = 29 时满足上述两个条件 1 < 29 < 144 5 *29 mod 144 = 145 mod 144 = 1 此时私钥=(D ,N )=(29 ,323 )
私钥和公钥都可以拿去解析
这里解析得到
1 2 3 4 5 e = 65537 n =86934482296048119190666062003494800588905656017203025617216654058378322103517 (n拿去分解)p = 285960468890451637935629440372639283459 q = 304008741604601924494328155975272418463
从文件读取公钥或者私钥
1 2 3 4 with open ('private .pem', mode='rb') as privatefile: keydata = privatefile.read() #rb 是以二进制形式打开文件 privkey = rsa.PrivateKey . load_pkcs1(keydata )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import gmpy2 import rsa e = 65537 n = 86934482296048119190666062003494800588905656017203025617216654058378322103517 p = 285960468890451637935629440372639283459 q = 304008741604601924494328155975272418463 phin = (q-1 )*(p-1 )d = gmpy2.invert(e, phin)key = rsa.PrivateKey(n, e, int(d), p, q)with open("D:\\new\\题目\\output\\flag.enc" , "rb+" ) as f: f = f.read() print(rsa.decrypt(f, key))
Maze
Maze题一般都需要找到入口、出口还有移动方向
题目——unctf20201—easymaze
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 int __cdecl main(int argc, const char **argv, const char **envp) { __int64 *v3; // rax char *v4; // rdi unsigned __int64 v5; // rbx const char *v6; // rdx int v7; // eax int v8; // er9 int v9; // er8 int v10; // edx char v11; // cl int v12; // ecx int v13; // ecx __int64 *v14; // rax sub_1400011A0(argc, argv, envp); dword_140006790[0] = 1; dword_140006794 = 1; dword_1400067B4 = 1; dword_1400067CC = 1; dword_1400067EC = 1; dword_1400067F0 = 1; dword_1400067D4 = 1; dword_1400067D8 = 1; dword_1400067F8 = 1; dword_140006810 = 1; dword_14000682C = 1; dword_140006844 = 1; dword_140006840 = 1; dword_140006864 = 1; dword_140006868 = 1; dword_140006884 = 1; dword_1400068A0 = 1; dword_1400068BC = 1; dword_1400068DC = 1; dword_14000689C = 1; v3 = sub_140001800(std::cout, (__int64)"Plz inpu7 the P4th :" ); std::ostream::operator<<(v3, sub_1400019D0); v4 = input; v5 = -1i64; sub_140001AA0(std::cin, -1i64, input); do ++v5; while ( input[v5] ); if ( v5 > 0x11 ) { v6 = "to0 lon9!t0o long!" ; goto LABEL_26; } if ( v5 < 0x11 ) { v6 = (const char *)&unk_140003770; goto LABEL_26; } v7 = dword_140006710; v8 = 0; v9 = dword_140006714; v10 = dword_140006710; do { v11 = *v4; if ( *v4 == 'A' ) goto LABEL_21; if ( v11 == 'W' ) { ++v10; v12 = v7 % 2; ++v7; goto LABEL_20; } if ( v11 == 'E' ) { ++v10; v13 = v7 % 2; ++v7; LABEL_16: dword_140006710 = v7; if ( v13 ) goto LABEL_23; goto LABEL_17; } if ( v11 != 'D' ) { if ( v11 != 'X' ) { if ( v11 != 'Z' ) { v6 = "What the fuck did you give me?" ; goto LABEL_26; } --v10; v12 = v7 % 2; --v7; LABEL_20: dword_140006710 = v7; if ( !v12 ) goto LABEL_23; LABEL_21: --v9; goto LABEL_22; } --v10; v13 = v7 % 2; --v7; goto LABEL_16; } LABEL_17: ++v9; LABEL_22: dword_140006714 = v9; LABEL_23: ++v8; ++v4; } while ( v8 < v5 ); v6 = "Congratulations on this forced to get the right flag, you entered is the correct answer!" ; if ( dword_140006790[7 * v7 + v9] != 1 ) v6 = "Try it again little unlucky!" ; LABEL_26: v14 = sub_140001800(std::cout, (__int64)v6); std::ostream::operator<<(v14, sub_1400019D0); return 0; }
动调就可以把AWEDXZ的移动弄出来
在ida里面dd表示四个字节,db表示一个字节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 data :00007FF673BF6794 dword_7FF673BF6794 dd 0 ; DATA XREF : main+27↑w.data :00007FF673BF6798 dd 0 .data :00007FF673BF679C db 0 .data :00007FF673BF679D db 0 .data :00007FF673BF679E db 0 .data :00007FF673BF679F db 0 .data :00007FF673BF67A0 db 0 .data :00007FF673BF67A1 db 0 .data :00007FF673BF67A2 db 0 .data :00007FF673BF67A3 db 0 .data :00007FF673BF67A4 db 0 .data :00007FF673BF67A5 db 0 .data :00007FF673BF67A6 db 0 .data :00007FF673BF67A7 db 0
要对着db按D转换数据类型,全部转为int型
base64变表
1、base64变表实际上就是将base64编码表进行了修改
2、题目——nctf2021 shadowbringer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 int __cdecl main (int argc, const char **argv, const char **envp) { char v4[16 ]; char v5[15 ]; char v6; char v7[16 ]; char v8[16 ]; char v9[16 ]; char v10[32 ]; _main(); youknowwhat (); std::string::string ((std::string *)v5); std::allocator<char >::allocator (&v6); std::string::string (v4, "U>F2UsQXN`5sXMELT=:7M_2<X]^1ThaWF0=KM?9IUhAsTM5:T==_Ns&<Vhb!" , &v6); std::allocator<char >::~allocator (&v6); std::operator <<<std::char_traits<char >>(printf_0, "Welcome.Please input your flag:\n" ); std::operator >><char >(scanf, (std::string *)v5); std::string::string ((std::string *)v8, (const std::string *)v5); Emet (v7, v8); std::string::operator =(v5, v7); std::string::~string ((std::string *)v7); std::string::~string ((std::string *)v8); std::string::string ((std::string *)v10, (const std::string *)v5); Selch (v9, v10); std::string::operator =(v5, v9); std::string::~string ((std::string *)v9); std::string::~string ((std::string *)v10); if ( (unsigned __int8)std::operator ==<char >(v5, v4) ) std::operator <<<std::char_traits<char >>(printf_0, "Right." ); else std::operator <<<std::char_traits<char >>(printf_0, "Wrong." ); std::string::~string ((std::string *)v4); std::string::~string ((std::string *)v5); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 std::string *__fastcall Emet (std::string *a1, std::string *a2) { int i; char *v3; unsigned __int64 v4; int j; unsigned int v6; char *v7; unsigned __int64 v9; char v10; char v11; char v12[16 ]; char v13[16 ]; char v14[16 ]; char v15[16 ]; char v16[16 ]; char v17[16 ]; char v18[16 ]; char v19[16 ]; std::allocator<char >::allocator (&v10); std::string::string (&v9, &unk_48A000, &v10); std::allocator<char >::~allocator (&v10); std::allocator<char >::allocator (&v11); std::string::string (a1, &unk_48A000, &v11); std::allocator<char >::~allocator (&v11); for ( i = 0 ; i < (unsigned __int64)std::string::size (a2); ++i ) { v3 = (char *)std::string::operator [](a2, i); std::bitset<8ull>::bitset (v14, (unsigned int )*v3); std::bitset<8ull>::to_string (v13, v14); std::operator +<char >(v12, &v9, v13); std::string::operator =(&v9, v12); std::string::~string ((std::string *)v12); std::string::~string ((std::string *)v13); } while ( 1 ) { v4 = std::string::size ((std::string *)&v9); if ( v4 == 6 * (v4 / 6 ) ) break ; std::operator +<char >(v15, &v9, 48 i64); std::string::operator =(&v9, v15); std::string::~string ((std::string *)v15); } for ( j = 0 ; j < (unsigned __int64)std::string::size ((std::string *)&v9); j += 6 ) { std::string::substr ((std::string *)v18, (unsigned __int64)&v9, j); std::bitset<6ull>::bitset<char ,std::char_traits<char >,std::allocator<char >>(v17, v18, 0 i64); v6 = std::bitset<6ull >::to_ulong (v17); v7 = (char *)std::string::operator [](&hisoralce, v6); std::operator +<char >(v16, a1, (unsigned int )*v7); std::string::operator =(a1, v16); std::string::~string ((std::string *)v16); std::string::~string ((std::string *)v18); } while ( (std::string::size (a1) & 3 ) != 0 ) { std::operator +<char >(v19, a1, 33 i64); std::string::operator =(a1, v19); std::string::~string ((std::string *)v19); } std::string::~string ((std::string *)&v9); return a1; }
这里的j+=6,像是base64,而&hisorale是指针
1 2 3 4 5 6 7 8 9 10 bss: 00000000004AA030 hisoralce db 28h .bss: 00000000004AA030 .bss: 00000000004AA031 db 3Dh .bss: 00000000004AA032 db 0BBh .bss: 00000000004AA033 db 0 .bss: 00000000004AA034 db 0 .bss: 00000000004AA035 db 0 .bss: 00000000004AA036 db 0 .bss: 00000000004AA037 db 0
需要对着db按d转换类型,才能看到该地址存储的内容