本文共 1204 字,大约阅读时间需要 4 分钟。
内存布局是程序运行时将内存划分的逻辑区域。根据需求,程序会将内存分成代码区、堆栈、堆和常量区。
局部变量是在函数内部定义的变量。其特点包括:
函数变量的反汇编通常是[ebp-4]
或[ebp-8]
,表示在ebp指针所指的位置减去一定偏移量处的值。
全局变量是在程序运行时始终存在的变量,其特点包括:
全局变量的反汇编通常是mov寄存器, byte/word/dword ds:[0x12345678]
。
参数传递方式可能通过堆栈或寄存器完成。常见的传递方式包括standard calling和fastcall。传递方式取决于如何将参数值从调用函数的上下文传输到目标函数的参数位置。码可以是:
push ebxpush eaxmov ecx, dword ptr ds: []mov ecx, dword ptr ds: []push 45push 33call 函数地址
参数是否通过寄存器传递可以通过kernel_movie magnusμ ... 来判断。
堆数组通常用于存储大量数据。初始化方式包括静态初始化或动态分配。访问数组时需要确认索引是否合理。
void Function() { printf("%d\n", arr);}int arr[10] = {1, 3, 7, 2, 8, 11, 5, 23, 22, 10};
输出结果为4354848。读取单个元素时,需确保索引在数组范围内。
int x = arr[9];printf("%d\n", x);
输出结果为10。
if语句通过跳转实现条件控制。cmp指令用于修改标志寄存器,紧接着的是jcc指令。asmlinkage函数应该 jumps到正确的分支。
if (x > y) { // x大于y时执行} else { // else执行}
elseif通过多次cmp和jcc实现。逆向分析可验证分支是否处于激活状态。
根据技术文档,大致确定可执行的组件。重点关注中间模块的功能,合理分布参数。注意缓存机制和预先定义的函数返回值。例如:
[DllImport("kernel32.dll")]static uint sprintf(IntPtr hBuf, IntPtr pFormat, char[] arg);int Program_Start() { // 功能描述 return 0;}int main() { // 主程序内容 return 0;}
返回值存储在eax中。
转载地址:http://pjjyk.baihongyu.com/