攻防世界逆向刷题wp Newbie

    科技2024-08-05  26

    Newbie_calculations

    做逆向c语言要扎实呀,这里有用到指针的知识点。

    用exeinfope分析发现没壳

    用ida打开先看main函数

    int __cdecl main(int argc, const char **argv, const char **envp) { _DWORD *v3; // eax _DWORD *v4; // eax _DWORD *v5; // eax _DWORD *v6; // eax int v7; // eax _DWORD *v8; // eax _DWORD *v9; // eax _DWORD *v10; // eax _DWORD *v11; // eax _DWORD *v12; // eax _DWORD *v13; // eax _DWORD *v14; // eax _DWORD *v15; // eax _DWORD *v16; // eax _DWORD *v17; // eax _DWORD *v18; // eax _DWORD *v19; // eax _DWORD *v20; // eax _DWORD *v21; // eax _DWORD *v22; // eax _DWORD *v23; // eax _DWORD *v24; // eax _DWORD *v25; // eax _DWORD *v26; // eax _DWORD *v27; // eax _DWORD *v28; // eax _DWORD *v29; // eax _DWORD *v30; // eax _DWORD *v31; // eax _DWORD *v32; // eax _DWORD *v33; // eax _DWORD *v34; // eax _DWORD *v35; // eax _DWORD *v36; // eax _DWORD *v37; // eax _DWORD *v38; // eax _DWORD *v39; // eax int v40; // eax int v41; // eax int v42; // eax int v43; // eax int v44; // eax int v45; // eax int v46; // eax _DWORD *v47; // eax _DWORD *v48; // eax _DWORD *v49; // eax int v50; // eax _DWORD *v51; // eax _DWORD *v52; // eax _DWORD *v53; // eax int v54; // eax int v55; // eax int v56; // eax int v57; // eax int v58; // eax int v59; // eax int v60; // eax _DWORD *v61; // eax _DWORD *v62; // eax _DWORD *v63; // eax int v64; // eax int v65; // eax int v66; // eax int v67; // eax int v68; // eax int v69; // eax int v70; // eax int v71; // eax int v72; // eax int v73; // eax int v74; // eax int v75; // eax int v76; // eax int v77; // eax int v78; // eax _DWORD *v79; // eax _DWORD *v80; // eax _DWORD *v81; // eax _DWORD *v82; // eax _DWORD *v83; // eax _DWORD *v84; // eax _DWORD *v85; // eax _DWORD *v86; // eax _DWORD *v87; // eax _DWORD *v88; // eax _DWORD *v89; // eax _DWORD *v90; // eax _DWORD *v91; // eax _DWORD *v92; // eax _DWORD *v93; // eax _DWORD *v94; // eax _DWORD *v95; // eax _DWORD *v96; // eax int v97; // eax int v98; // eax int v99; // eax int v100; // eax int v101; // eax int v102; // eax int v103; // eax int v104; // eax _DWORD *v105; // eax _DWORD *v106; // eax _DWORD *v107; // eax _DWORD *v108; // eax int v109; // ST1C_4 _DWORD *v110; // eax _DWORD *v111; // eax int v112; // ST20_4 _DWORD *v113; // eax _DWORD *v114; // eax int v115; // ST20_4 _DWORD *v116; // eax signed int i; // [esp+4h] [ebp-90h] signed int j; // [esp+8h] [ebp-8Ch] int v120[32]; // [esp+Ch] [ebp-88h] int v121; // [esp+8Ch] [ebp-8h] for ( i = 0; i < 32; ++i ) v120[i] = 1; v121 = 0; puts("Your flag is:"); v3 = sub_401100(v120, 1000000000); v4 = sub_401220(v3, 999999950); sub_401100(v4, 2); v5 = (_DWORD *)sub_401000(&v120[1], 5000000); v6 = sub_401220(v5, 6666666); v7 = sub_401000(v6, 1666666); v8 = (_DWORD *)sub_401000(v7, 45); v9 = sub_401100(v8, 2); sub_401000(v9, 5); v10 = sub_401100(&v120[2], 1000000000); v11 = sub_401220(v10, 999999950); v12 = sub_401100(v11, 2); sub_401000(v12, 2); v13 = (_DWORD *)sub_401000(&v120[3], 55); v14 = sub_401220(v13, 3); v15 = (_DWORD *)sub_401000(v14, 4); sub_401220(v15, 1); v16 = sub_401100(&v120[4], 100000000); v17 = sub_401220(v16, 99999950); v18 = sub_401100(v17, 2); sub_401000(v18, 2); v19 = sub_401220(&v120[5], 1); v20 = sub_401100(v19, 1000000000); v21 = (_DWORD *)sub_401000(v20, 55); sub_401220(v21, 3); v22 = sub_401100(&v120[6], 1000000); v23 = sub_401220(v22, 999975); sub_401100(v23, 4); v24 = (_DWORD *)sub_401000(&v120[7], 55); v25 = sub_401220(v24, 33); v26 = (_DWORD *)sub_401000(v25, 44); sub_401220(v26, 11); v27 = sub_401100(&v120[8], 10); v28 = sub_401220(v27, 5); v29 = sub_401100(v28, 8); sub_401000(v29, 9); v30 = (_DWORD *)sub_401000(&v120[9], 0); v31 = sub_401220(v30, 0); v32 = (_DWORD *)sub_401000(v31, 11); v33 = sub_401220(v32, 11); sub_401000(v33, 53); v34 = (_DWORD *)sub_401000(&v120[10], 49); v35 = sub_401220(v34, 2); v36 = (_DWORD *)sub_401000(v35, 4); sub_401220(v36, 2); v37 = sub_401100(&v120[11], 1000000); v38 = sub_401220(v37, 999999); v39 = sub_401100(v38, 4); sub_401000(v39, 50); v40 = sub_401000(&v120[12], 1); v41 = sub_401000(v40, 1); v42 = sub_401000(v41, 1); v43 = sub_401000(v42, 1); v44 = sub_401000(v43, 1); v45 = sub_401000(v44, 1); v46 = sub_401000(v45, 10); sub_401000(v46, 32); v47 = sub_401100(&v120[13], 10); v48 = sub_401220(v47, 5); v49 = sub_401100(v48, 8); v50 = sub_401000(v49, 9); sub_401000(v50, 48); v51 = sub_401220(&v120[14], 1); v52 = sub_401100(v51, -294967296); v53 = (_DWORD *)sub_401000(v52, 55); sub_401220(v53, 3); v54 = sub_401000(&v120[15], 1); v55 = sub_401000(v54, 2); v56 = sub_401000(v55, 3); v57 = sub_401000(v56, 4); v58 = sub_401000(v57, 5); v59 = sub_401000(v58, 6); v60 = sub_401000(v59, 7); sub_401000(v60, 20); v61 = sub_401100(&v120[16], 10); v62 = sub_401220(v61, 5); v63 = sub_401100(v62, 8); v64 = sub_401000(v63, 9); sub_401000(v64, 48); v65 = sub_401000(&v120[17], 7); v66 = sub_401000(v65, 6); v67 = sub_401000(v66, 5); v68 = sub_401000(v67, 4); v69 = sub_401000(v68, 3); v70 = sub_401000(v69, 2); v71 = sub_401000(v70, 1); sub_401000(v71, 20); v72 = sub_401000(&v120[18], 7); v73 = sub_401000(v72, 2); v74 = sub_401000(v73, 4); v75 = sub_401000(v74, 3); v76 = sub_401000(v75, 6); v77 = sub_401000(v76, 5); v78 = sub_401000(v77, 1); sub_401000(v78, 20); v79 = sub_401100(&v120[19], 1000000); v80 = sub_401220(v79, 999999); v81 = sub_401100(v80, 4); v82 = (_DWORD *)sub_401000(v81, 50); sub_401220(v82, 1); v83 = sub_401220(&v120[20], 1); v84 = sub_401100(v83, -294967296); v85 = (_DWORD *)sub_401000(v84, 49); sub_401220(v85, 1); v86 = sub_401220(&v120[21], 1); v87 = sub_401100(v86, 1000000000); v88 = (_DWORD *)sub_401000(v87, 54); v89 = sub_401220(v88, 1); v90 = (_DWORD *)sub_401000(v89, 1000000000); sub_401220(v90, 1000000000); v91 = (_DWORD *)sub_401000(&v120[22], 49); v92 = sub_401220(v91, 1); v93 = (_DWORD *)sub_401000(v92, 2); sub_401220(v93, 1); v94 = sub_401100(&v120[23], 10); v95 = sub_401220(v94, 5); v96 = sub_401100(v95, 8); v97 = sub_401000(v96, 9); sub_401000(v97, 48); v98 = sub_401000(&v120[24], 1); v99 = sub_401000(v98, 3); v100 = sub_401000(v99, 3); v101 = sub_401000(v100, 3); v102 = sub_401000(v101, 6); v103 = sub_401000(v102, 6); v104 = sub_401000(v103, 6); sub_401000(v104, 20); v105 = (_DWORD *)sub_401000(&v120[25], 55); v106 = sub_401220(v105, 33); v107 = (_DWORD *)sub_401000(v106, 44); v108 = sub_401220(v107, 11); sub_401000(v108, 42); sub_401000(&v120[26], v120[25]); sub_401000(&v120[27], v120[12]); v109 = v120[27]; v110 = sub_401220(&v120[28], 1); v111 = (_DWORD *)sub_401000(v110, v109); sub_401220(v111, 1); v112 = v120[23]; v113 = sub_401220(&v120[29], 1); v114 = sub_401100(v113, 1000000); sub_401000(v114, v112); v115 = v120[27]; v116 = (_DWORD *)sub_401000(&v120[30], 1); sub_401100(v116, v115); sub_401000(&v120[31], v120[30]); sub_401C7F("CTF{"); for ( j = 0; j < 32; ++j ) sub_401C7F("%c", SLOBYTE(v120[j])); sub_401C7F("}\n"); return 0; }

    分析代码,一开始程序将32位数组v120赋值为1

    然后调用三类函数改变v120,最后将v120输出

    sub_401100 sub_401220 sub_401000

    现在来看看这三个函数是用来干什么的

    _DWORD *__cdecl sub_401100(_DWORD *a1, int a2) //函数需要一个地址a1和一个数值a2 { int v2; // ST20_4 signed int v4; // [esp+Ch] [ebp-1Ch] int v5; // [esp+14h] [ebp-14h] int v6; // [esp+18h] [ebp-10h] int v7; // [esp+1Ch] [ebp-Ch] int v8; // [esp+20h] [ebp-8h] v5 = *a1; //让v5存储a1地址中的数值 v6 = a2; //让v6存储数值a2 v4 = -1; v8 = 0; v7 = a2 * v5; //让v7等于a2 * a1地址中的数值 while ( a2 ) //运行a2次 { v2 = v7 * v5; //v2 = v7 * a1地址中的数值 sub_401000(&v8, *a1); //调用了一个函数将v8的值进行了改变,先去看看 ++v7; //让v7+1 --a2; //让a2-1 v6 = v2 - 1; //v6 = v7 * a1地址中的数值 - 1 } //发现v8数据只有发生到sub_401000函数中发生过变化 while ( v4 ) //v4 = -1 而里面的判断条件却是--v4。这里我理解为,这是逆过来的,循环里的++就是--,--就是++ { ++v7; //相当于--v7 ++*a1; //相当于--*a1 --v4; //相当于++v4 --v6; //相当于--v6 } //发现这里循环只做了一次,a1的值只是-1了即*a1 = *a1-1 ++*a1; //这里又给加回来了 *a1 = *a1 +1 *a1 = v8; //这里将v8赋值给了*a1,而v8只在上面sub_401000函数中发生过变化,现在去看看sub_401000函数做了什么事 return a1; //明白了sub_401000函数其实就是*a1 = *a1+a2时,由while(a2)和--a2;可知v8做了a2次的加法,相当于v8 = *a1 + *a1 ... +*a1,加了a2次,就是v8 = *a1 * a2,然后将v8赋值给了*a1,函数返回a1。这个函数的作用就是*a1 = *a1 * a2 } int *__cdecl sub_401000(int *a1, int a2)//函数需要一个地址a1和一个数值a2 { int v2; // edx int v4; // [esp+Ch] [ebp-18h] signed int v5; // [esp+10h] [ebp-14h] int v6; // [esp+18h] [ebp-Ch] signed int v7; // [esp+1Ch] [ebp-8h] v5 = -1; v4 = -1 - a2 + 1; //将v4 = -a2 v7 = 1231; v2 = *a1; v6 = a2 + 1231; while ( v4 ) //v4 = -a2,这里可以将循环中的运算逆过来,循环里的++就是--,--就是++ { ++v7; //相当于--v7 --*a1; //相当于++*a1 --v4; //相当于++v4 --v6; //相当于--v6 } //这里相当于*a1 = *a1 + 1 + 1 ....+1,加了a2次1,即*a1 = *a1 + a2 while ( v5 ) //v5 = -1 这里可以将循环中的运算逆过来,循环里的++就是--,--就是++ { --v6; //相当于++v6; ++*a1; //相当于--*a1; --v5; //相当于++v5; } //发现这里循环只做了一次,a1的值只是-1了即*a1 = *a1-1 ++*a1; //这里又给加回来了 *a1 = *a1 +1 return a1; //这个函数的作用就是*a1 = *a1 + a2 } _DWORD *__cdecl sub_401220(_DWORD *a1, int a2)//函数需要一个地址a1和一个数值a2 { int v3; // [esp+8h] [ebp-10h] signed int v4; // [esp+Ch] [ebp-Ch] signed int v5; // [esp+14h] [ebp-4h] int v6; // [esp+14h] [ebp-4h] v4 = -1; v3 = -1 - a2 + 1; //将v3 = -a2 v5 = -1; while ( v3 ) //v3 = -a2,这里可以将循环中的运算逆过来,循环里的++就是--,--就是++ { ++*a1; //相当于--*a1; --v3; //相当于++v3; --v5; //相当于++v5; } //这里相当于*a1 = *a1 - 1 - 1 ....-1,减了a2次1,即*a1 = *a1 - a2 v6 = v5 * v5; while ( v4 ) //v4 = -1 这里可以将循环中的运算逆过来,循环里的++就是--,--就是++ { v6 *= 123; ++*a1; //--*a1; --v4; //++v4; } //发现这里循环只做了一次,a1的值只是-1了即*a1 = *a1-1 ++*a1; //这里又给加回来了 *a1 = *a1 +1 return a1; //这个函数的作用就是*a1 = *a1 - a2 }

    现在知道了三个函数的作用,就可以写脚本,得到flag了

    这里就有一个有趣的地方了,我直接运行时没有结果的,需要我一步一步调试才有输出,我这里不能明白,希望由师傅指点指点

    #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <stdlib.h> using namespace std; int *sub_401100(int *a1, int a2)//a1 * a2 { *a1 = *a1 * a2; return a1; } int *sub_401000(int *a1, int a2)//a1 + a2 { *a1 = *a1 + a2; return a1; } int *sub_401220(int *a1, int a2)//a1 - a2 { *a1 = *a1 -a2; return a1; } int main() { int *v3; // eax int *v4; // eax int *v5; // eax int *v6; // eax int *v7; // eax int *v8; // eax int *v9; // eax int *v10; // eax int *v11; // eax int *v12; // eax int *v13; // eax int *v14; // eax int *v15; // eax int *v16; // eax int *v17; // eax int *v18; // eax int *v19; // eax int *v20; // eax int *v21; // eax int *v22; // eax int *v23; // eax int *v24; // eax int *v25; // eax int *v26; // eax int *v27; // eax int *v28; // eax int *v29; // eax int *v30; // eax int *v31; // eax int *v32; // eax int *v33; // eax int *v34; // eax int *v35; // eax int *v36; // eax int *v37; // eax int *v38; // eax int *v39; // eax int *v40; // eax int *v41; // eax int *v42; // eax int *v43; // eax int *v44; // eax int *v45; // eax int *v46; // eax int *v47; // eax int *v48; // eax int *v49; // eax int *v50; // eax int *v51; // eax int *v52; // eax int *v53; // eax int *v54; // eax int *v55; // eax int *v56; // eax int *v57; // eax int *v58; // eax int *v59; // eax int *v60; // eax int *v61; // eax int *v62; // eax int *v63; // eax int *v64; // eax int *v65; // eax int *v66; // eax int *v67; // eax int *v68; // eax int *v69; // eax int *v70; // eax int *v71; // eax int *v72; // eax int *v73; // eax int *v74; // eax int *v75; // eax int *v76; // eax int *v77; // eax int *v78; // eax int *v79; // eax int *v80; // eax int *v81; // eax int *v82; // eax int *v83; // eax int *v84; // eax int *v85; // eax int *v86; // eax int *v87; // eax int *v88; // eax int *v89; // eax int *v90; // eax int *v91; // eax int *v92; // eax int *v93; // eax int *v94; // eax int *v95; // eax int *v96; // eax int *v97; // eax int *v98; // eax int *v99; // eax int *v100; // eax int *v101; // eax int *v102; // eax int *v103; // eax int *v104; // eax int *v105; // eax int *v106; // eax int *v107; // eax int *v108; // eax int *v109; // ST1C_4 int *v110; // eax int *v111; // eax int *v112; // ST20_4 int *v113; // eax int *v114; // eax int *v115; // ST20_4 int *v116; // eax signed int i; // [esp+4h] [ebp-90h] signed int j; // [esp+8h] [ebp-8Ch] int v120[33]; // [esp+Ch] [ebp-88h] int v121; // [esp+10h] [ebp-84h] for ( i = 0; i < 32; ++i ) v120[i] = 1; v121 = 0; puts("Your flag is:"); v3 = sub_401100(&v120[0], 1000000000); v4 = sub_401220(v3, 999999950); sub_401100(v4, 2); v5 = sub_401000(&v120[1], 5000000); v6 = sub_401220(v5, 6666666); v7 = sub_401000(v6, 1666666); v8 = sub_401000(v7, 45); v9 = sub_401100(v8, 2); sub_401000(v9, 5); v10 = sub_401100(&v120[2], 1000000000); v11 = sub_401220(v10, 999999950); v12 = sub_401100(v11, 2); sub_401000(v12, 2); v13 = sub_401000(&v120[3], 55); v14 = sub_401220(v13, 3); v15 = sub_401000(v14, 4); sub_401220(v15, 1); v16 = sub_401100(&v120[4], 100000000); v17 = sub_401220(v16, 99999950); v18 = sub_401100(v17, 2); sub_401000(v18, 2); v19 = sub_401220(&v120[5], 1); v20 = sub_401100(v19, 1000000000); v21 = sub_401000(v20, 55); sub_401220(v21, 3); v22 = sub_401100(&v120[6], 1000000); v23 = sub_401220(v22, 999975); sub_401100(v23, 4); v24 = sub_401000(&v120[7], 55); v25 = sub_401220(v24, 33); v26 = sub_401000(v25, 44); sub_401220(v26, 11); v27 = sub_401100(&v120[8], 10); v28 = sub_401220(v27, 5); v29 = sub_401100(v28, 8); sub_401000(v29, 9); v30 = sub_401000(&v120[9], 0); v31 = sub_401220(v30, 0); v32 = sub_401000(v31, 11); v33 = sub_401220(v32, 11); sub_401000(v33, 53); v34 = sub_401000(&v120[10], 49); v35 = sub_401220(v34, 2); v36 = sub_401000(v35, 4); sub_401220(v36, 2); v37 = sub_401100(&v120[11], 1000000); v38 = sub_401220(v37, 999999); v39 = sub_401100(v38, 4); sub_401000(v39, 50); v40 = sub_401000(&v120[12], 1); v41 = sub_401000(v40, 1); v42 = sub_401000(v41, 1); v43 = sub_401000(v42, 1); v44 = sub_401000(v43, 1); v45 = sub_401000(v44, 1); v46 = sub_401000(v45, 10); sub_401000(v46, 32); v47 = sub_401100(&v120[13], 10); v48 = sub_401220(v47, 5); v49 = sub_401100(v48, 8); v50 = sub_401000(v49, 9); sub_401000(v50, 48); v51 = sub_401220(&v120[14], 1); v52 = sub_401100(v51, -294967296); v53 = sub_401000(v52, 55); sub_401220(v53, 3); v54 = sub_401000(&v120[15], 1); v55 = sub_401000(v54, 2); v56 = sub_401000(v55, 3); v57 = sub_401000(v56, 4); v58 = sub_401000(v57, 5); v59 = sub_401000(v58, 6); v60 = sub_401000(v59, 7); sub_401000(v60, 20); v61 = sub_401100(&v120[16], 10); v62 = sub_401220(v61, 5); v63 = sub_401100(v62, 8); v64 = sub_401000(v63, 9); sub_401000(v64, 48); v65 = sub_401000(&v120[17], 7); v66 = sub_401000(v65, 6); v67 = sub_401000(v66, 5); v68 = sub_401000(v67, 4); v69 = sub_401000(v68, 3); v70 = sub_401000(v69, 2); v71 = sub_401000(v70, 1); sub_401000(v71, 20); v72 = sub_401000(&v120[18], 7); v73 = sub_401000(v72, 2); v74 = sub_401000(v73, 4); v75 = sub_401000(v74, 3); v76 = sub_401000(v75, 6); v77 = sub_401000(v76, 5); v78 = sub_401000(v77, 1); sub_401000(v78, 20); v79 = sub_401100(&v120[19], 1000000); v80 = sub_401220(v79, 999999); v81 = sub_401100(v80, 4); v82 = sub_401000(v81, 50); sub_401220(v82, 1); v83 = sub_401220(&v120[20], 1); v84 = sub_401100(v83, -294967296); v85 = sub_401000(v84, 49); sub_401220(v85, 1); v86 = sub_401220(&v120[21], 1); v87 = sub_401100(v86, 1000000000); v88 = sub_401000(v87, 54); v89 = sub_401220(v88, 1); v90 = sub_401000(v89, 1000000000); sub_401220(v90, 1000000000); v91 = sub_401000(&v120[22], 49); v92 = sub_401220(v91, 1); v93 = sub_401000(v92, 2); sub_401220(v93, 1); v94 = sub_401100(&v120[23], 10); v95 = sub_401220(v94, 5); v96 = sub_401100(v95, 8); v97 = sub_401000(v96, 9); sub_401000(v97, 48); v98 = sub_401000(&v120[24], 1); v99 = sub_401000(v98, 3); v100 = sub_401000(v99, 3); v101 = sub_401000(v100, 3); v102 = sub_401000(v101, 6); v103 = sub_401000(v102, 6); v104 = sub_401000(v103, 6); sub_401000(v104, 20); v105 = sub_401000(&v120[25], 55); v106 = sub_401220(v105, 33); v107 = sub_401000(v106, 44); v108 = sub_401220(v107, 11); sub_401000(v108, 42); sub_401000(&v120[26], v120[25]); sub_401000(&v120[27], v120[12]); *v109 = v120[27]; v110 = sub_401220(&v120[28], 1); v111 = sub_401000(v110, *v109); sub_401220(v111, 1); *v112 = v120[23]; v113 = sub_401220(&v120[29], 1); v114 = sub_401100(v113, 1000000); sub_401000(v114, v120[23]); v116 = sub_401000(&v120[30], 1); sub_401100(v116, v120[27]); sub_401000(&v120[31], v120[30]); printf("CTF{"); for ( j = 0; j < 32; ++j ) printf("%c", v120[j]); printf("}\n"); return 0; }

    Processed: 0.009, SQL: 8