首页 > 其他分享 >天堂之门

天堂之门

时间:2024-04-23 21:34:09浏览次数:16  
标签:X86 32 mu 行号 64 天堂 bits

天堂之门

WoW64是Windows x64提供的一种兼容机制,可以认为WoW64是64位Windows系统创建的一个32位的模拟环境,使得32位可执行程序能够在64位的操作系统上正常运行

所以也弄明白了之前为什么32位的dll需要放在WoW64里面了,而64位的dll需要放在System32里面

image-20240423122920623

系统运行程序的时候,会检测CS段寄存器的值来调用API

CS为0x33的时候会切换到64位模式,当CS为0x23的时候就会切换到32位模式

下面通过天堂之门技术调用WIN32 API的过程。这里我们通过一些操作绕过了WoW64机制,手动切换到64位模式并调用64位下的ZwOpenProcess函数,大致流程如下(和图中不太一样):

  1. 将cs段寄存器设为0x33,切换到64位模式
  2. 从gs:0x60读取64位PEB
  3. 从64位PEB中定位64位ntdll基址
  4. 遍历ntdll64导出表,读取ZwOpenProcess函数地址
  5. 构造64位函数调用

结合最近的做题,我总结就是找到更改cs段寄存器值的地方,然后根据汇编找到跳转的对应地址

关注0X33和0x23和关键的汇编指令 jmp far ptr.....

dump下来可以用bn看,然后就可以逆向解密,最近发现了ida的一个插件

OllyDumpEx · Issue #41 · mentebinaria/retoolkit (github.com)

也是可以直接在ida里面直接dump了,对于调试可以使用windbg或者CE(目前对于这两个的使用还差的很多,还要学)

unicorn

Unicorn 是一个轻量级, 多平台, 多架构的 CPU 模拟器框架. 我们可以更好地关注 CPU 操作, 忽略机器设备的差异. 想象一下, 我们可以将其应用于这些情景: 比如我们单纯只是需要模拟代码的执行而非需要一个真的 CPU 去完成那些操作, 又或者想要更安全地分析恶意代码, 检测病毒特征, 或者想要在逆向过程中验证某些代码的含义. 使用 CPU 模拟器可以很好地帮助我们提供便捷.

Programming with C & Python languages – Unicorn – The Ultimate CPU emulator (unicorn-engine.org)

它的亮点 (这也归功于 Unicorn 是基于 qemu 而开发的) 有:

  • 支持多种架构: Arm, Arm64 (Armv8), M68K, Mips, Sparc, & X86 (include X86_64).
  • 对 Windows 和 nix 系统 (已确认包含 Mac OSX, Linux, BSD & Solaris) 的原生支持
  • 具有平台独立且简洁易于使用的 API
  • 使用 JIT 编译技术, 性能表现优异

官方文档里讲了c和python接口,这里主要说一下python接口

 1 from __future__ import print_function
 2 from unicorn import *
 3 from unicorn.x86_const import *
 4 
 5 # code to be emulated
 6 X86_CODE32 = b"\x41\x4a" # INC ecx; DEC edx
 7 
 8 # memory address where emulation starts
 9 ADDRESS = 0x1000000
10 
11 print("Emulate i386 code")
12 try:
13     # Initialize emulator in X86-32bit mode
14     mu = Uc(UC_ARCH_X86, UC_MODE_32)
15 
16     # map 2MB memory for this emulation
17     mu.mem_map(ADDRESS, 2 * 1024 * 1024)
18 
19     # write machine code to be emulated to memory
20     mu.mem_write(ADDRESS, X86_CODE32)
21 
22     # initialize machine registers
23     mu.reg_write(UC_X86_REG_ECX, 0x1234)
24     mu.reg_write(UC_X86_REG_EDX, 0x7890)
25 
26     # emulate code in infinite time & unlimited instructions
27     mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE32))
28 
29     # now print out some registers
30     print("Emulation done. Below is the CPU context")
31 
32     r_ecx = mu.reg_read(UC_X86_REG_ECX)
33     r_edx = mu.reg_read(UC_X86_REG_EDX)
34     print(">>> ECX = 0x%x" %r_ecx)
35     print(">>> EDX = 0x%x" %r_edx)
36 
37 except UcError as e:
38     print("ERROR: %s" % e)
  • 行号 2~3: 在使用 Unicorn 前导入unicorn模块. 样例中使用了一些 x86 寄存器常量, 所以也需要导入unicorn.x86_const模块
  • 行号 6: 这是我们需要模拟的二进制机器码, 使用十六进制表示, 代表的汇编指令是: "INC ecx" 和 "DEC edx".
  • 行号 9: 我们将模拟执行上述指令的所在虚拟地址
  • 行号 14: 使用Uc类初始化 Unicorn, 该类接受 2 个参数: 硬件架构和硬件位数 (模式). 在样例中我们需要模拟执行 x86 架构的 32 位代码, 我 们使用变量mu来接受返回值.
  • 行号 17: 使用mem_map方法根据在行号 9 处声明的地址, 映射 2MB 用于模拟执行的内存空间. 所有进程中的 CPU 操作都应该只访问该内存区域. 映射的内存具有默认的读, 写和执行权限.
  • 行号 20: 将需要模拟执行的代码写入我们刚刚映射的内存中. mem_write方法接受 2 个参数: 要写入的内存地址和需要写入内存的代码.
  • 行号 23~24: 使用reg_write方法设置ECX和EDX寄存器的值
  • 行号 27: 使用emu_start方法开始模拟执行, 该 API 接受 4 个参数: 要模拟执行的代码地址, 模拟执行停止的内存地址 (这里是 X86_CODE32的最后 1 字节处), 模拟执行的时间和需要执行的指令数目. 如果我们像样例一样忽略后两个参数, Unicorn 将会默认以无穷时间和无穷指令数目的条件来模拟执行代码.
  • 行号 32~35: 打印输出ECX和EDX寄存器的值. 我们使用函数reg_read来读取寄存器的值.

后面对于这个的使用会补上一些题....

每日一题

image-20240423124321508

最开始点进来发现是一串数字,c了过后感觉也不太对,觉得是SMC,然后动态走一下,小改一下花指令

image-20240423124530028

基本可以确定是SMC了,然后调试开始乱飞

从这里开始飞,然后根据逻辑判断这里也是关键的加密部分image-20240423124753744

image-20240423133939148

jmp far ptr可以知道的是可以同时改变eip和cs段寄存器值的指令

这种格式的jmp指令实现的是上述的段间转移,同时修改CS和IP,在跳转范围大于-32768~32767时使用jmp near ptr不会编译失败,但是会链接失败。
该指令执行后CS:IP将同时修改

这个不要看反汇编指令,其实是跳转的是4011D0这个地址,修改的CS段寄存器为0X33

然后可以在bn里设置64位然后查看反汇编,有个反调试PEB.BeingDebugged

记得绕过

dump下来后可以看见

image-20240423172644654

image-20240423172806348

image-20240423172815371

最后求flag的过程不难,就是简单的异或和循环左移右移

贴一个其他师傅写的脚本

rol = lambda val, r_bits, max_bits: \
    (val << r_bits%max_bits) & (2**max_bits-1) | \
    ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
ror = lambda val, r_bits, max_bits: \
    ((val & (2**max_bits-1)) >> r_bits%max_bits) | \
    (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
flag = b'1234adc89012345678901234a27890ab'
cmp = [0xAA, 0x4F, 0x0F, 0xE2, 0xE4, 0x41, 0x99, 0x54, 0x2C, 0x2B, 0x84, 0x7E, 0xBC, 0x8F, 0x8B, 0x78, 0xD3, 0x73, 0x88, 0x5E, 0xAE, 0x47, 0x85, 0x70, 0x31, 0xB3, 0x09, 0xCE, 0x13, 0xF5, 0x0D, 0xCA]

# key = [0x9d,0x44,0x37,0xb5]
key = [4,0x77,0x82, 0x4a]
print(bytes(cmp))
print()
def enc(flag):
    enc = b''
    num = 0x3CA7259D
    for i in range(8):
        cur = int.from_bytes(flag[4*i:4*i+4],'little')
        cur = (cur+num)&0xffffffff
        num ^= cur
        enc += cur.to_bytes(4,'little')
    print("enc1 ", enc)
    enc = bytearray(enc )

    cur = int.from_bytes(enc[0:8],'little')
    enc[0:8] = rol(cur,0xc, 64).to_bytes(8,'little')
    cur = int.from_bytes(enc[8:16],'little')
    enc[8:16] = rol(cur,0x22, 64).to_bytes(8,'little')
    cur = int.from_bytes(enc[16:24],'little')
    enc[16:24] = rol(cur,0x38, 64).to_bytes(8,'little')
    cur = int.from_bytes(enc[24:32],'little')
    enc[24:32] = rol(cur,0xe, 64).to_bytes(8,'little')
    # for i in range(4):
    #     enc[i*8:i*8+4], enc[i*8+4:i*8+8] = enc[i*8+4:i*8+8], enc[i*8:i*8+4],
    print("enc2 ", bytes(enc))
    
    for i in range(32):
        enc[i] ^= key[i%4]
    print("enc3 ", enc)

    
    return enc 

def dec(cmp):
    print("dec3 ", cmp)
    dec = [0]*32
    cmp = bytearray(cmp)
    
    for i in range(32):
        cmp[i] ^= key[i%4]
    
    print("dec2 ", cmp)
    # for i in range(4):
    #     cmp[i*8:i*8+4], cmp[i*8+4:i*8+8] = cmp[i*8+4:i*8+8], cmp[i*8:i*8+4]
    cur = int.from_bytes(cmp[0:8],'little')
    cmp[0:8] = ror(cur,0xc, 64).to_bytes(8,'little')
    cur = int.from_bytes(cmp[8:16],'little')
    cmp[8:16] = ror(cur,0x22, 64).to_bytes(8,'little')
    cur = int.from_bytes(cmp[16:24],'little')
    cmp[16:24] = ror(cur,0x38, 64).to_bytes(8,'little')
    cur = int.from_bytes(cmp[24:32],'little')
    cmp[24:32] = ror(cur,0xe, 64).to_bytes(8,'little')
    print("dec1 ", bytes(cmp))
    
    num = 0x3CA7259D
    for i in range(8):
        num ^= int.from_bytes(cmp[4*i:4*i+4],'little')
    for i in range(7,-1,-1):
        cur = int.from_bytes(cmp[4*i:4*i+4],'little')
        num ^= cur
        cur = (cur+0x100000000-num)&0xffffffff
        dec[4*i:4*i+4] = cur.to_bytes(4,'little')
    return bytes(dec)


assert(dec(enc(flag)) == flag)



print('----------------------')
print(dec(cmp))  # 6cc1e44811647d38a15017e389b3f704

标签:X86,32,mu,行号,64,天堂,bits
From: https://www.cnblogs.com/CCb0nd/p/18153782

相关文章

  • 天堂之门(Heaven's Gate)逆向
    Heaven'sGate原理及POC通过在32位WoW进程中执行64位代码,实现静态反编译以及干扰对Win32Api的检测实现免杀。详见[原创]天堂之门(Heaven'sGate)C语言实现-软件逆向-看雪-安全社区|安全招聘|kanxue.com常见的打开天堂之门的代码块//convertx86tox646A33......
  • 天堂2如何对版本里面的内容进行修改
    天堂2写装备属性的问题早一点的版本属性都是写在armor文件夹xml档里,不再写armor里了armor文件夹里只有防御HPMP增加量,套装的属性都用一个技能形式写在skills里了在配合数据库里一个叫armorsets实现套装属性,拿皇家套做说明。id43套装idchest6373皇家骑士团胸甲legs6374......
  • 任天堂Switch全部记录
    title:任天堂Switch全部记录date:2023-10-2215:11:48tags:switchcategories:switchNSSWTICH大气层制作新的SD卡,解决部分大气层及固件问题。原先的SD卡(128G)快全部放满游戏了,需要新的内存卡用于存放新的游戏。有几张闲置的内存卡,可是容量最大只有64G,无法通过直接全部......
  • 天堂2服务器基本设置
    [system]server_name=LocalServer——〉服务器名称server_rules=PvPhttp_host=127.0.0.1——〉HTTP注册页面(需先搭建IIS服务器)http_port=8080rs_host=127.0.0.1——〉填IPrs_port=3724ws_host=127.0.0.1——〉填你的IPws_port=8085world_sleep_ms=500——〉照字面来看是白天的......
  • scrapy电影天堂练习
    movie.pyimportscrapyfrommovieProject.itemsimportMovieprojectItemclassMovieSpider(scrapy.Spider):name='movie'allowed_domains=['www.ygdy8.net']start_urls=['https://www.ygdy8.net/html/gndy/china/index.......
  • 寻找理想的退休天堂:我对美国人选择海外退休地的见解和分析
    在我多年的研究与探索过程中,我不断寻找答案:为什么越来越多的美国人选择在海外度过他们的退休时光?我将带您深入探讨这一现象,让我们一起破解其中的奥秘。1.寻找专家意见在开始这一探索之旅前,我首先寻找了该领域的知名专家。RichardFlorida和WilliamH.Frey是人口迁移研究领......
  • 对于任天堂你了解多少?
    图灵教育的一本《任天堂传奇:游戏产业之王者归来》预计将于3月上旬上市,对于任天堂大家肯定一点也不陌生,它是日本最著名的游戏制作公司。在本书中介绍了任天堂之所以成为行业领袖的主要因素,讲述了其DS和Wii游戏机的开发以及新游戏平台的创建等内容。在本书上市之前,我想您和我一样,都想......
  • 许久不见,甚是想念,天堂之上,愿你安好!
    这是杂货铺的第446篇文章2018年的3月17日,北京下了这个冬天以来唯一一场大雪,这一天我这辈子都不会忘记,就是在这天,我们的爱犬妞妞,在我的怀抱中,永远离开了我们。时光荏苒,妞妞离开,已经有整整一年,15年的感情,不可能轻易抿灭,有时感觉,就像昨天一样,在他得病的日子,一种无法诉说的感情,往日的点......
  • hls--季末的天堂
    https://www.cnblogs.com/jimodetiantang/tag/HLS/SRS之SrsHlsCache::reap_segment详解SRS之SrsHls::on_audio详解SRS之SrsHls::on_video详解HLS协议解析SRS之分发HLS   ......
  • scrapy:电影天堂案例
    嵌套数据封装成一个item(一个item包含多级页面的数据):每条记录的名称+点进去之后第二页中的图片1.创建爬虫项目scrapystartprojectscrapy_movie_52.创建爬虫文件scrapygenspidermvhttps://www.ygdy8.net/html/gndy/china/index.html3.实现爬虫importsc......