PC端逆向入门

一、什么是逆向

某乎上的概念是这样的

逆向工程(又称反向工程),是一种技术过程,即对一项目标产品进行逆向分析及研究,从而演绎并得出该产品的处理流程、组织结构、功能性能规格等设计要素,以制作出功能相近,但又不完全一样的产品。逆向工程源于商业及军事领域中的硬件分析。其主要目的是,在不能轻易获得必要的生产信息下,直接从成品的分析,推导出产品的设计原理。

我个人认为嘛,是通过一些手段深入挖掘软件的运行过程,以至能够控制软件的运行流程,或者可以还原软件源码,来取得逆向的目标

二、逆向常用工具及教程

OllyDbg 3级调试工具,与当年的TRW2000(RING 0级调试工具)齐名,用的人很多。上手容易,教程如牛毛。只能用来搞32位程序,作者已不再更新

x64dbg 新型的调试工具 32位 64位 都能搞,相对bug多,教程少;但是!越来用的人越多。周更新

IDA 可动态、静态、流程图式分析与调试,占用资源也最多

下载地址:爱盘 (自行检索)

教程链接:idaolldbgx64dbg

三、CTF中简单题型介绍

下列题目对应的文件已隐写到文章末尾的logo中,请自取(如果你不会隐写,那么看这里:压缩文件分析及解决隐写与压缩文件分析实战

1、普通exe可执行文件 ——flag.exe

exe既然是可执行的,那么我们将它拉进虚拟机后直接运行看看

这样无头绪的试肯定是试不出来的,所以我们用ollydbg来打开它(按照我的习惯,exe一般优先考虑ollydbg)

点击ollydbg的调试运行按钮后,对中文信息进行搜索,按下CTRL+F来搜索 “错误” 这个关键词

然后我们观察上下文后发现了”可疑“的字符串HackAv,我们将它输入后,成功破解

最后得到的flag就是:flag{HackAv}

2、linux下64位可执行文件 ——re1

不论是windows还是linux,按照我的平时习惯,那我们肯定是要先运行起来看看会发生什么

但是这里的题目还是比较简单的,有些难题不止是要破解一次,所以可以先运行看看是否能找到提示信息

为了方便,我这里直接用IDA打开

可以发现这里直接给出了flag:flag{7ujm8ikhy6}

3、稍复杂的linux下64位可执行文件 ——re3

这题运行后只能看到一个error,我们还是直接用IDA打开

但是经过一番查看,没有发现什么有价值的信息

利用hex_rays_decompiler插件进行反编译成易读c代码

argc != 5     // 这里可以看出该程序接受4个参数
// 从f函数中可以看出v4的范围在2-200之间
// v9由函数f生成
// 那么传入的4个参数分别是v4、v10、v11、v12
// 传入的v4要加上25923

根据几个条件判断语句,我们可以还原出程序执行过程,枚举出参数,并解出flag

import binascii

def f(a, v3=0):
    ptr = [0] * a
    ptr[0] = ptr[1] = 1
    for i in range(2, a):
        ptr[i] = ptr[i - 1] + ptr[i - 2]
        v3 = ptr[i]
    return v3

if __name__ == '__main__':
    for v4 in range(2, 201):
        v9 = f(v4)
        v10 = v9 - 151381742876
        v11 = v9 - 117138004530
        v12 = v9 - 155894355749
        if v4 + v12 + v11 + v10 == 1349446086540:
            print( binascii.a2b_hex('%x%x%x%x' % (v10, v11, v12, v4 + 25923) ).decode() )

# flag{newbee_here}

4、 可反编译代码文件 ——re3.pyc

安装pyc反编译工具,进行反编译

pip2 install uncompyle6
uncompyle6 re3.pyc > re3.py

得到代码

# uncompyle6 version 3.6.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.17 (default, Jan 19 2020, 19:54:54) 
# [GCC 9.2.1 20200110]
# Embedded file name: re3.py
# Compiled at: 2020-03-06 17:43:28
import string
c_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '()'
flag = 'BozjB3vlZ3ThBn9bZ2jhOH93ZaH9'

def encode(origin_bytes):
    c_bytes = [ ('{:0>8}').format(str(bin(b)).replace('0b', '')) for b in origin_bytes ]
    resp = ''
    nums = len(c_bytes) // 3
    remain = len(c_bytes) % 3
    integral_part = c_bytes[0:3 * nums]
    while integral_part:
        tmp_unit = ('').join(integral_part[0:3])
        tmp_unit = [ int(tmp_unit[x:x + 6], 2) for x in [0, 6, 12, 18] ]
        resp += ('').join([ c_charset[i] for i in tmp_unit ])
        integral_part = integral_part[3:]

    if remain:
        remain_part = ('').join(c_bytes[3 * nums:]) + (3 - remain) * '0' * 8
        tmp_unit = [ int(remain_part[x:x + 6], 2) for x in [0, 6, 12, 18] ][:remain + 1]
        resp += ('').join([ c_charset[i] for i in tmp_unit ]) + (3 - remain) * '.'
    return rend(resp)


def rend(s):

    def encodeCh(ch):
        f = lambda x: chr((ord(ch) - x + 2) % 26 + x)
        if ch.islower():
            return f(97)
        if ch.isupper():
            return f(65)
        return ch

    return ('').join(encodeCh(c) for c in s)

# okay decompiling re3.pyc

经过分析可以看出,encode (origin_bytes) 函数是base64加密,encodeCh(ch)) 函数是凯撒移位加密。(不会的小伙伴先看这里:密码学

然后我们进行反推,先凯撒移位后base64解码

import base64

# 凯撒
def carsar(string, n):
    t = ''
    for i in range(0, len(string)):
        if 'A' <= string[i] <= 'Z':
            num = ord(string[i]) - 65 - n
            t += chr(num % 26 + 65)
        elif 'a' <= string[i] <= 'z':
            num = ord(string[i]) - 97 - n
            t += chr(num % 26 + 97)
        else:
            t += string[i]
    return t

if __name__ == '__main__':
    flag = 'BozjB3vlZ3ThBn9bZ2jhOH93ZaH9'
    tmp = carsar(flag, 2)
    print(base64.b64decode(tmp).decode())

# flag{c_t_f_s_h_0_w_!}


发表评论

路人甲

网友评论(0)