编译器是MingGW生成的可执行文件的显著特点是, 最终运行ZwContinue后程序就莫名其妙启动了, 也找不到main函数。
为了探究里面究竟怎么回事, 我找到了wrk-v1.2的源码, 其中包含了ZwContinue的实现, 首先先看一下注释, API界面包含了2个参数, 其中让人感兴趣的是PCONTEXT, 这是一个线程上下文环境, 其中包含了线程的执行环境, 也许main函数主线程就是位于这个上下文环境中。
先忘了原本的目的, 既然都来了, 看一下这个API的实现。
其中ZwContinue实现里, 实际上只是简单调用了_KiContinue
看一下KiContinue的调用界面:
首先其将IRQL提升到APC_LEVEL, 根据之前的用户模式来决定如何把线程上下文拷贝到内核框架, 如果之前是内核态就直接拷贝, 否则就调用KiContinuePreviousModeUser来拷贝。
看一下KiContinuePreviousModeUser, 其调用KeContextToKframes把线程上下文环境保存到KTRAP_FRAME上。所以其内部还是调用了KeContextToKframes。唯一的区别就是一个PreviousMode是KernelMode, 另一个是UserMode。
KeContextToKFrames把KTRAP_FRAME的内容保存到xmm寄存器后, 调用了KxContextToKframes
接着看一下KxContextToKframes的界面, 这个API才是真正把CONTEXT拷贝到KTRAP_FRAME上
看一下它的部分代码:
话题转回来。所以现在可以知道的ZwContinue是为了把线程上下文拷贝到TrapFrame上。方便让线程继续运行。所以我猜测ZwContinue中的CONTEXT, 其中EIP指向的就是main函数。
首先找到CONTEXT内容:
往下一拉, 就能找到对应的main函数的入口点。
找到0x4012A0, 然后这个call就是
进去之后首先是C/C++运行时库的代码:
可以看到非常明显的C/C++运行时库的代码, 蓝色框的就是main函数了。
最后在看一眼
(完)