我目前正在尝试实现结合逆向工程和图论的东西.因此,我想拆解PE二进制文件.有一些非常复杂的工具可以这样做,比如IDA或w32dasm.后来似乎死了.IDA不是可编写脚本的 - 据我所知.
我想要一个可编写脚本的反汇编程序的原因是,我在C#中实现了我的程序.它得到一个二进制文件,因此必须以某种方式获取操作码.我想我需要用一些参数调用一些帮助程序.没有GUI就无法调用IDA.它不提供真正的cmdline选项.
有任何想法吗?
谢谢,愿
我有用16bit delphi制作的PE文件.我整天都在尝试在这个文件上使用WriteProcessMemory().它不起作用.我在骗子引擎中找不到地址,也找不到tsearch.Peid说文件不是PE,我猜那是因为16位?
您对如何阅读这些地址有什么想法吗?如果需要,我可以发布exe.
unsigned char hexData[14] = {
0x31, 0xC0, 0xBB, 0x42, 0x24, 0x80, 0x7C, 0x66,
0xB8, 0x88, 0x13, 0x50, 0xFF, 0xD3
};
void dummy(){}
int main()
{
void *code_ptr = &dummy;
PDWORD OP;
__asm
{
call code_ptr
add code_ptr,10h
}
VirtualProtect(code_ptr, 14, PAGE_EXECUTE_WRITECOPY, OP);
memcpy(code_ptr, hexData, 14);
.
.
.
Run Code Online (Sandbox Code Playgroud)
并在拆卸
_LoadLibraryA@4:
003C11E0 jmp _LoadLibraryA@4 (03C1430h)
dummy:
003C11E5 jmp dummy (03C1A80h)
_printf:
003C11EA jmp _printf (03C1436h)
_VirtualProtect@16:
003C11EF jmp _VirtualProtect@16 (03C143Ch)
003C11F4 int 3
003C11F5 int 3
003C11F6 int 3
003C11F7 int …Run Code Online (Sandbox Code Playgroud) 我已经(用汇编器,没有链接器)制作了一个 x86-64 的 EXE,它在 Linux 下的 Wine 中运行得非常好。这是一个调用 MessageBoxA 和 ExitProcess 的基本 HelloWorld。
Windows 10 无法识别它,并说“此程序无法在您的计算机上执行,请与您的供应商联系以获取适合您计算机的版本”。
我使用 PE 格式阅读器(PE 工具和 CFF Explorer)来分析我的 PE EXE。PE Optional 标头中的所有数字与其他工作 EXE(如操作系统版本、子系统版本)中的相同。只有特定于我的文件和部分的那些是不同的。Windows 不会将该文件识别为我的计算机上的可执行文件。
除了 WINdows 错误消息,我还能从哪里开始看?是否有任何工具可以通过比“Bad exe”更具体的错误消息来检查 EXE 的有效性?(这是 xdbg 报告的内容。
在 Wine 上,我能够做到
WINEDEBUG=+all wine my.exe
,这让我知道出了什么问题,我能够修复它并使其正常工作。Windows 中有这样的工具吗?
BITS 64
falign equ 1000h ; section file position modulo
imageBase equ 400000h
; MZ header
DOSHDR:
db 0x4D, 0x5A, 0x90, 0,
dd 3, 4, 0xFFFF, 0xB8, 0, 0x40, 0, 0, 0, 0, 0, 0, 0, …Run Code Online (Sandbox Code Playgroud) 问题是将可移植可执行映像加载到随机地址。
我们以kernel32.dll为例,加载于0x75A00000。
我可以看到在图像的偏移 0x10e15 处有一条汇编指令,这取决于图像所在的位置。
地址:75A10E13 字节:8B 35 18 03 AE 75 命令:MOV ESI,DWORD PTR DS:[75AE0318]
事实证明,通过启动可执行文件,我们必须告诉系统我们需要重定位到这个地址。
系统查看可执行文件中的重定位表,并看到以下内容: 基本重定位表
为了获取要移动的第一个元素的绝对地址,我执行以下操作:将虚拟地址添加到图像的地址,然后将块的第一个元素添加到结果数字。
0x75A00000 + 0x10000 + 0x3E15 = 75A10E15
这是一个很好的数字,但总是比我预期多 0x3000。我只需减去 0x3000 就可以了。请帮我找到答案,x86 的 0x3000 从哪里来?
我试图读取PE头,并想看看exe是否启用了ASLR.
我目前在做:
if (PE.FileHeader->OptionalHeader.DllCharacteristics == IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)
std::cout << "ASLR is enabled :)" << std::endl;
else
std::cout << "ASLR is disabled >:(" << std::endl;
Run Code Online (Sandbox Code Playgroud)
但是,我总是得到"ASLR被禁用> :(",即使我知道ASLR已启用.
我知道这与我的运算符有关,但我如何测试并查看PE头是否具有某个WORD字符?
今天,仅出于测试目的,我提出了以下想法,在CodeBlocks中创建和编译一个天真的源代码,使用Release目标来删除不必要的调试代码,一个带有三个nop操作的主函数只能找到更快的条目点的主要功能是.
CodeBlocks样本天真程序:
使用IDA反汇编程序,我看到一些奇怪的东西,OS实际上可以在main函数中添加aditional机器代码调用(隐式添加),调用系统函数,它驻留在kernel32.dll中,用于OS线程处理.
IDA计划视图:
在机器代码中仅出于测试原因将三个"nop"(90)替换为"和esp,0FFFFFFF0h",程序再次被重新缓存,这就是为什么"无操作"操作码在视图中不可取消的原因.
观察到的行为:
为每个进程创建一个新线程是逻辑,因为我们可以在TaskManager中探索它,这是一个在它自己的线程中运行的进程,这就是编译器添加此代码的原因(隐式默认线程).
我的问题:
编译器如何知道自动"注入"此调用代码的位置?
为什么之前没有在上层函数(sub_401B8C)中进行此调用,该函数将路由到主函数入口点?