软件调试-PE & call convention

 

单步:Flags寄存器中的标志位,CPU每执行一条指令后会检查IF位值。如为1则产生调试异常。

断点:使用INT 3替代目标指令头,执行时候则产生调试异常切换到调试器,而后返回时恢复

分支踪迹存储:记录最后一次JMP的地址,LastBranchRecording

系统中对对应的中断向量表,当中断产生时,PUSH现场,查询对应表中对应序号的地址,赋予CSIP,使之执行中断程序,而后恢复现场。表中包含了中断与异常(软中断)。

软件同时运行在用户空间、内核空间(前者主要包括CPUGPU计算,后者包括IO,系统时间等获取),故调试时候会发生模式切换:软中断与快速系统调用

快速系统调用软中断相似,跳过了执行中断前的一系列权限检查

用户态调试:调试器程序,被调试进程,调试子系统(事件驱动)

进程的虚拟内存空间:共享的系统内容与独立的进程内存

进程&线程:进程控制块/进程环境块;线程内核对象/线程环境块

 

栈与函数调用

每个线程都至少有一个栈,系统线程外的有两个栈:内核空间与用户空间

调用过程与约定

Push P1

Push P2

Call   Func1   // push IP   +  JMP Func1

Push BP

Push Var1

Push Var2

POP Var2, Var1, BP, IP, P2, P1

C约定调用,Pop P2, P1 caller执行,接受可变参数

标准调用,   callee销毁P2,P1;该过程指令不必反复出现在caller

快速调用,   部分参数通过寄存器传递,速度快

以上可能发生的溢出与下溢

堆的分配过程:

进程空间中的堆 -----堆管理器 ------内存管理器

堆器管理器维护着堆表,进程释放对空间时,返回给堆管理器(标为未使用);内存管理器为堆管理器请求分配内存空间

 

code

 

#include <stdlib.h>
#include <stdio.h>

 int __cdecl func2(int a, int b, int c, int d)
{
     int f = a + b;
     int e = c * d;
    return f+e;
}

int __stdcall func1(short a, long b)
{
    int f = a + b;
    return f;
}

int __fastcall func3(short a, int b, int c, int d)
{
    int f = a + b;
    int e = c * d;
    return f + e;
}

int main()
{

    int i = 0;
    int a, b, c, d, f;
    long aa = 12;
    a = 3, b = 4, c = 5, d = 6;
    if (i = 0) i += 1;
    for (; i < 5; i++) {}

    // call convention
    f = func2(a, b, c, d);
    f = func1(a, aa);
    f = func3(a,b,c,d);
    return 0;
}

 

 

 

 

posted @ 2018-01-07 23:18  HEIS老妖  阅读(240)  评论(4编辑  收藏  举报