1. 程式人生 > 實用技巧 >小白學逆向8.2筆記

小白學逆向8.2筆記

BUUCTF

刮開有獎

查殼,32位無殼檔案

用ida開啟

檢視WinMain函式的虛擬碼

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  DialogBoxParamA(hInstance, (LPCSTR)0x67, 0, DialogFunc, 0);
  return 0;
}

找到函式DialogFunc,反編譯為虛擬碼

BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
  
const char *v4; // esi const char *v5; // edi int v7; // [esp+8h] [ebp-20030h] int v8; // [esp+Ch] [ebp-2002Ch] int v9; // [esp+10h] [ebp-20028h] int v10; // [esp+14h] [ebp-20024h] int v11; // [esp+18h] [ebp-20020h] int v12; // [esp+1Ch] [ebp-2001Ch] int v13; // [esp+20h] [ebp-20018h] int v14; // [esp+24h] [ebp-20014h] int
v15; // [esp+28h] [ebp-20010h] int v16; // [esp+2Ch] [ebp-2000Ch] int v17; // [esp+30h] [ebp-20008h] CHAR String; // [esp+34h] [ebp-20004h] char v19; // [esp+35h] [ebp-20003h] char v20; // [esp+36h] [ebp-20002h] char v21; // [esp+37h] [ebp-20001h] char v22; // [esp+38h] [ebp-20000h] char v23; // [esp+39h] [ebp-1FFFFh] char v24; //
[esp+3Ah] [ebp-1FFFEh] char v25; // [esp+3Bh] [ebp-1FFFDh] char v26; // [esp+10034h] [ebp-10004h] char v27; // [esp+10035h] [ebp-10003h] char v28; // [esp+10036h] [ebp-10002h] if ( a2 == 272 ) return 1; if ( a2 != 273 ) return 0; if ( (_WORD)a3 == 1001 ) { memset(&String, 0, 0xFFFFu); GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF);//String是我們輸入的flag if ( strlen(&String) == 8 ) //flag的長度為8 { v7 = 90; v8 = 74; v9 = 83; v10 = 69; v11 = 67; v12 = 97; v13 = 78; v14 = 72; v15 = 51; v16 = 110; v17 = 103; sub_4010F0(&v7, 0, 10); //在對v7-v17進行某種操作,進入sub_4010F0函式,將函式轉換為c語言程式碼,再將v7-v17代入 memset(&v26, 0, 0xFFFFu); v26 = v23; v28 = v25; v27 = v24; v4 = (const char *)sub_401000(&v26, strlen(&v26)); memset(&v26, 0, 0xFFFFu); v27 = v21; v26 = v20; v28 = v22; v5 = (const char *)sub_401000(&v26, strlen(&v26)); if ( String == v7 + 34 && v19 == v11 && 4 * v20 - 141 == 3 * v9 && v21 / 4 == 2 * (v14 / 9) && !strcmp(v4, "ak1w") && !strcmp(v5, "V1Ax") ) { MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0); } } return 0; } if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 ) return 0; EndDialog(hDlg, (unsigned __int16)a3); return 1; }
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

int __cdecl sub_4010F0(char *a1, int a2, int a3)
{
    int result; // eax
    int i; // esi
    int v5; // ecx
    int v6; // edx

    result = a3;
    for (i = a2; i <= a3; a2 = i)
    {
        v5 = i;
        v6 = a1[i];
        if (a2 < result && i < result)
        {
            do
            {
                if (v6 >a1[result])
                {
                    if (i >= result)
                        break;
                    ++i;
                    a1[v5] = a1[result];
                    if (i >= result)
                        break;
                    while (a1[i] <= v6)
                    {
                        if (++i >= result)
                            goto LABEL_13;
                    }
                    if (i >= result)
                        break;
                    v5 = i;
                    a1[result] = a1[i];
                }
                --result;
            } while (i < result);
        }
    LABEL_13:
        a1[result] = v6;
        sub_4010F0(a1, a2, i - 1);
        result = a3;
        ++i;
    }
    return result;
}

char str[20] = { 90,74,83,69,67,97,78,72,51,110,103 };

int main()
{
    cout << str << endl;

    sub_4010F0(str, 0, 10);

    for (int i = 0; i < 11; ++i) {
        cout << str[i];
    }
    return 0;
}

執行得到

分析52-58程式碼,轉到彙編

.text:004012B0                 push    0FFFFh          ; size_t
.text:004012B5                 lea     edx, [ebp+var_10004]
.text:004012BB                 push    0               ; int
.text:004012BD                 push    edx             ; void *
.text:004012BE                 call    _memset
.text:004012C3                 mov     al, [ebp+var_1FFFF]  //
.text:004012C9                 mov     dl, [ebp+var_1FFFD]  //
.text:004012CF                 mov     cl, [ebp+var_1FFFE]  //
.text:004012D5                 mov     [ebp+var_10004], al
.text:004012DB                 lea     eax, [ebp+var_10004]
.text:004012E1                 mov     [ebp+var_10002], dl
.text:004012E7                 add     esp, 18h
.text:004012EA                 mov     [ebp+var_10003], cl
.text:004012F0                 lea     edx, [eax+1]
.text:004012F3
.text:004012F3 loc_4012F3:                             ; CODE XREF: DialogFunc+158↓j
.text:004012F3                 mov     cl, [eax]
.text:004012F5                 inc     eax
.text:004012F6                 test    cl, cl
.text:004012F8                 jnz     short loc_4012F3
.text:004012FA                 sub     eax, edx
.text:004012FC                 push    eax
.text:004012FD                 lea     eax, [ebp+var_10004]
.text:00401303                 push    eax
.text:00401304                 call    sub_401000
.text:00401309                 push    0FFFFh          ; size_t
.text:0040130E                 lea     ecx, [ebp+var_10004]
.text:00401314                 push    0               ; int
.text:00401316                 push    ecx             ; void *
.text:00401317                 mov     esi, eax
.text:00401319                 call    _memset
.text:0040131E                 mov     al, [ebp+var_20001]  //
.text:00401324                 mov     dl, [ebp+var_20002]  //
.text:0040132A                 mov     cl, [ebp+var_20000]  //
.text:00401330                 mov     [ebp+var_10003], al
.text:00401336                 lea     eax, [ebp+var_10004]
.text:0040133C                 mov     [ebp+var_10004], dl
.text:00401342                 add     esp, 14h
.text:00401345                 mov     [ebp+var_10002], cl
.text:0040134B                 lea     edx, [eax+1]
.text:0040134E                 mov     edi, edi

觀看//處

-00020004 String          db ?
-00020003 var_20003       db ?
-00020002 var_20002       db ?
-00020001 var_20001       db ?
-00020000 var_20000       db ?
-0001FFFF var_1FFFF       db ?
-0001FFFE var_1FFFE       db ?
-0001FFFD var_1FFFD       db ?

我們可以知道,v6使用sub_4010F0函式後的字串的6,7,8位,呼叫sub_401000函式,v7使用sub_4010F0函式後的字串的3,4,5位,呼叫sub_401000函式。

進入sub_401000

 1 _BYTE *__cdecl sub_401000(int a1, int a2)
 2 {
 3   int v2; // eax
 4   int v3; // esi
 5   size_t v4; // ebx
 6   _BYTE *v5; // eax
 7   _BYTE *v6; // edi
 8   int v7; // eax
 9   _BYTE *v8; // ebx
10   int v9; // edi
11   signed int v10; // edx
12   int v11; // edi
13   signed int v12; // eax
14   signed int v13; // esi
15   _BYTE *result; // eax
16   _BYTE *v15; // [esp+Ch] [ebp-10h]
17   _BYTE *v16; // [esp+10h] [ebp-Ch]
18   int v17; // [esp+14h] [ebp-8h]
19   int v18; // [esp+18h] [ebp-4h]
20 
21   v2 = a2 / 3;
22   v3 = 0;
23   if ( a2 % 3 > 0 )
24     ++v2;
25   v4 = 4 * v2 + 1;
26   v5 = malloc(v4);
27   v6 = v5;
28   v15 = v5;
29   if ( !v5 )
30     exit(0);
31   memset(v5, 0, v4);
32   v7 = a2;
33   v8 = v6;
34   v16 = v6;
35   if ( a2 > 0 )
36   {
37     while ( 1 )
38     {
39       v9 = 0;
40       v10 = 0;
41       v18 = 0;
42       do
43       {
44         if ( v3 >= v7 )
45           break;
46         ++v10;
47         v9 = *(unsigned __int8 *)(v3++ + a1) | (v9 << 8);
48       }
49       while ( v10 < 3 );
50       v11 = v9 << 8 * (3 - v10);
51       v12 = 0;
52       v17 = v3;
53       v13 = 18;
54       do
55       {
56         if ( v10 >= v12 )
57         {
58           *((_BYTE *)&v18 + v12) = (v11 >> v13) & 0x3F;
59           v8 = v16;
60         }
61         else
62         {
63           *((_BYTE *)&v18 + v12) = 64;
64         }
65         *v8++ = byte_407830[*((char *)&v18 + v12)];進入byte_407830
66         v13 -= 6;
67         ++v12;
68         v16 = v8;
69       }
70       while ( v13 > -6 );
71       v3 = v17;
72       if ( v17 >= a2 )
73         break;
74       v7 = a2;
75     }
76     v6 = v15;
77   }
78   result = v6;
79   *v8 = 0;
80   return result;
81 }
.rdata:00407830 ; char byte_407830[]
.rdata:00407830 byte_407830     db 41h                  ; DATA XREF: sub_401000+C0↑r
.rdata:00407831 aBcdefghijklmno db 'BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',0

可以推測函式是base64加密

      if ( String == v9 + 34                    // sub_4010F0函式後的第一位等於51+34=85-->'U'
        && v21 == v13                           // 第2位,等於v13,即sub_4010F0函式返回值的第5位值-->'J'
        && 4 * v22 - 141 == 3 * v11
        && v23 / 4 == 2 * (v16 / 9)
        && !strcmp(v6, "ak1w")                  // 第6,7,8行程式碼base64之後,需要等於"ak1w"
        && !strcmp(                             // 第3,4,5行程式碼,加密之後等於V1Ax
              v7,
              "V1Ax") )
      {
        MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
      }

將v6,v7解密之後得到WP1jMp,再結合第1,2位得到flag{UJWP1jMp}

java逆向解密

使用jd-gui開啟檔案

import java.util.ArrayList;
import java.util.Scanner;

public class Reverse {
  public static void main(String[] args) {
    Scanner s = new Scanner(System.in);
    System.out.println("Please input the flag );
    String str = s.next();
    System.out.println("Your input is );
    System.out.println(str);
    char[] stringArr = str.toCharArray();
    Encrypt(stringArr);
  }
  
  public static void Encrypt(char[] arr) {
    ArrayList<Integer> Resultlist = new ArrayList<>();
    for (int i = 0; i < arr.length; i++) {
      int result = arr[i] + 64 ^ 0x20;
      Resultlist.add(Integer.valueOf(result));
    } 
    int[] KEY = { 
        180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 
        133, 191, 134, 140, 129, 135, 191, 65 };
    ArrayList<Integer> KEYList = new ArrayList<>();
    for (int j = 0; j < KEY.length; j++)
      KEYList.add(Integer.valueOf(KEY[j])); 
    System.out.println("Result:");
    if (Resultlist.equals(KEYList)) {
      System.out.println("Congratulations);
    } else {
      System.err.println("Error);
    } 
  }
}

一個列表運算,編寫指令碼

# -*- coding:utf-8 -*-

KEY = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136,
    133, 191, 134, 140, 129, 135, 191, 65]

flag = ''
for i in KEY:
    flag += chr((i^0x20)-64)
print ('flag{'+flag+'}')

flag{This_is_the_flag_!}

findit

使用改之理開啟,找到一組十六進位制數

轉換為字串為pvkq{m164675262033l4m49lnp7p9mnk28k75}

凱撒解密

model = "abcdefghijklmnopqrstuvwxyz"

str1 = "pvkq{m164675262033l4m49lnp7p9mnk28k75}"

for i in range(1,27):
    print("key=%d"%i, end='\n')
    for s in str1:
        if s.isalpha():
            n = model.find(s)
            s = model[n-i]
        print(s, end='')
    print('\n')
    key=1
    oujp{l164675262033k4l49kmo7o9lmj28j75}

    key=2
    ntio{k164675262033j4k49jln7n9kli28i75}

    key=3
    mshn{j164675262033i4j49ikm7m9jkh28h75}

    key=4
    lrgm{i164675262033h4i49hjl7l9ijg28g75}

    key=5
    kqfl{h164675262033g4h49gik7k9hif28f75}

    key=6
    jpek{g164675262033f4g49fhj7j9ghe28e75}

    key=7
    iodj{f164675262033e4f49egi7i9fgd28d75}

    key=8
    hnci{e164675262033d4e49dfh7h9efc28c75}

    key=9
    gmbh{d164675262033c4d49ceg7g9deb28b75}

    key=10
    flag{c164675262033b4c49bdf7f9cda28a75}

    key=11
    ekzf{b164675262033a4b49ace7e9bcz28z75}

    key=12
    djye{a164675262033z4a49zbd7d9aby28y75}

    key=13
    cixd{z164675262033y4z49yac7c9zax28x75}

    key=14
    bhwc{y164675262033x4y49xzb7b9yzw28w75}

    key=15
    agvb{x164675262033w4x49wya7a9xyv28v75}

    key=16
    zfua{w164675262033v4w49vxz7z9wxu28u75}

    key=17
    yetz{v164675262033u4v49uwy7y9vwt28t75}

    key=18
    xdsy{u164675262033t4u49tvx7x9uvs28s75}

    key=19
    wcrx{t164675262033s4t49suw7w9tur28r75}

    key=20
    vbqw{s164675262033r4s49rtv7v9stq28q75}

    key=21
    uapv{r164675262033q4r49qsu7u9rsp28p75}

    key=22
    tzou{q164675262033p4q49prt7t9qro28o75}

    key=23
    synt{p164675262033o4p49oqs7s9pqn28n75}

    key=24
    rxms{o164675262033n4o49npr7r9opm28m75}

    key=25
    qwlr{n164675262033m4n49moq7q9nol28l75}

    key=26
    pvkq{m164675262033l4m49lnp7p9mnk28k75}

得到flag{c164675262033b4c49bdf7f9cda28a75}