windows平台中让函数在main函数之前执行的方法

1.将要执行的代码写到类的构造函数中,并定义对应的全局变量
2.将要执行的代码写到TLS回调函数中
在c/c++中,我们都知道main函数是程序开始执行的地方,但是在进行反调试的时候,很多时候都需要调试检测函数在main函数之前执行。

1.将要执行的代码写到类的构造函数中,并定义对应的全局变量
在windows平台中,执行我们手写的main函数之前,系统会执行一段CRTstartup代码,对系统的堆栈、全局变量、命令行参数、环境变量等进行初始化操作。该方法就是利用windows在执行main函数之前先对全局变量进行初始化的系统机制,使得代码在main函数之前执行。样例代码如下:

#include<iostream>
#include<Windows.h>
using namespace std;
class Debug{
public:
Debug() {
cout << "I am runing before main!" << endl;
}
};
Debug t;
int main() {
cout << "I am main!" << endl;
return 0;
}

程序的输出结果如下所以:

I am runing before main!

I am main!

因此该方案可以在windows平台上正确运行。

2.将要执行的代码写到TLS回调函数中
Thread Local Storage(TLS),是Windows为解决一个进程中多个线程同时访问全局变量而提供的机制。TLS可以简单地由操作系统代为完成整个互斥过程,也可以由用户自己编写控制信号量的函数。当进程中的线程访问预先制定的内存空间时,操作系统会调用系统默认的或用户自定义的信号量函数,保证数据的完整性与正确性。
因此系统在调用main函数之前,会优先执行tls代码,在执行完TLS代码后,才会执行main函数中的代码。样例代码如下:

#include <Windows.h>
#include <tchar.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ntdll.lib")

void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
cout << "I am in Tls" << endl;
}

//linker spec通知链接器PE文件要创建TLS目录,注意X86和X64的区别
#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
#else
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:_tls_callback")
#endif
//创建TLS段
EXTERN_C
#ifdef _M_X64
#pragma const_seg (".CRT$XLB")
const
#else
#pragma data_seg (".CRT$XLB")
#endif
//end linker

//tls import定义多个回调函数
PIMAGE_TLS_CALLBACK _tls_callback[] = { TLS_CALLBACK, 0 };
#pragma data_seg ()
#pragma const_seg ()
//end

int main()
{

cout << "I am in main!" << endl;
return 0;

}

输出结果如下:

I am in Tls
I am in main!
请按任意键继续. . .

————————————————
版权声明:本文为CSDN博主「meanong」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/meanong/article/details/81163760

原文地址:https://www.cnblogs.com/yuanch2019/p/11637965.html

时间: 2024-09-30 10:46:38

windows平台中让函数在main函数之前执行的方法的相关文章

golang中的init函数以及main函数

首先我们看一个例子:init函数: init 函数可在package main中,可在其他package中,可在同一个package中出现多次. main函数 main 函数只能在package main中. 执行顺序 golang里面有两个保留的函数:init函数(能够应用于所有的package)和main函数(只能应用于package main).这两个函数在定义时不能有任何的参数和返回值. 虽然一个package里面可以写任意多个init函数,但这无论是对于可读性还是以后的可维护性来说,我

linux中c语言编程main函数和参数

linux下main函数的的标准调用函数的标准形式 int main(int char,char *argv[]) 在main函数的两个参数中,argc必须是整型变量,其是命令行的参数的数目,argv必须是指向字符串的指针数组,这些指针分别指向各个的命令行参数的地址. 原文地址:https://www.cnblogs.com/zoutingrong/p/12250466.html

C语言中的main函数以及main函数是如何被调用的

main函数是C语言中比较特殊的函数,C程序总是从main函数开始执行,main函数的原型是: 1 int main(int argc, char *argv[]); 其中argc是命令行参数的个数,argv是指向参数的各个指针所构成的数组. 当内核执行C程序时(使用一个exec函数),在调用main前先调用一个特殊的启动例程(什么鬼?).可执行程序文件将此启动例程指定为程序的起始地址--这是由连接编辑器设置的,而连接编辑器则是由C编译器调用.启动例程从内核取得命令行参数和环境变量值,然后为按上

mysql8.0 Server 在Windows平台中的安装、初始化和远程访问设置

mysql8.0 server安装1.下载mysql 8.0可以到mysql官网下载 https://dev.mysql.com/downloads/mysql 或者如下地址 mysql-8.0.13 Server windows X64安装文件http://libmysql.com/download2.安装mysql 8.0 我这边选择了custom定制安装 其中client也选中安装,用于控制台访问mysqlClinet C API library 也需要安装,为了后面基于mysql开发程序

Java基础复习(1) 为什么在java中我们要将main定义为一个static方法?

2015-10-20 以前学习java知识,只是跟着用到的代码跳着学了些,学的不全还错漏成片……恩,好惨! 思来想去,是必须要好好复习加整理下,不然写出来的东西真没法读了.所以,就从今儿起一点一点的啃下去吧. 回头创建了Class文件,又看到了熟悉的main函数……然后,有了标题的问题.那么,今天就回顾这个问题吧. 1 public class Review_p2 { 2 public static void main(String[] args) { 3 byte b = 3; 4 5 byt

windows平台使用SecureCRT+Xming实现图形界面来执行linux平台的一些图形程序

需求分析:windows平台下使用ssh远程连接linux服务器,实现图形界面来执行linux平台的一些程序,如system-config-kickstart.xeyes.等 实验环境:服务器端:CentOS6/CentOS7系统windows端:Windows10/8/7系统.SecureCRT, Xming 配置部分: linux服务器端 编辑/etc/ssh/sshd_conf文件,开启X11转发.# vim /etc/ssh/sshd_confX11Forwarding yes   #默

windows编程中关于“关闭窗口无法退出进程”的解决方法

一般会出现如下两种情况 1.WinMain函数中,最后阶段接收消息队列循环中,调用的GetMessage函数参数提供错误 如: while (GetMessage(&msg,hwnd, 0, 0))       {         TranslateMessage(&msg);         DispatchMessage(&msg);     } 这个错误往往是由于程序员疏忽大意造成的,个别编译器使用时会有自动补全(提示)功能,会提示GetMessage函数的第二个参数是一个H

win2003添加删除windows组件中无iis应用程序服务器项的解决方法

一.解决方法如下: 1.开始 -- 运行 ,输入c:\Windows\inf\sysoc.inf ,会打开这个文件; 找到 "[Components]" 这一段,在下面添加: " iis=iis.dll,OcEntry,iis.inf,,7 " .之后保存并关闭. 2.下载 iis6 安装包(附件下载), 解压到 D:/ 根目录下,方便使用; 3.开始 -- 运行 -- cmd ,打开命令行模式.执行下面两条命令: EXPand d:\IIS6\iis.dl_ c:

多玩YY语音的面试题:C++中如何在main()函数之前执行操作?

第一反应main()函数是所有函数执行的开始.但是问题是main()函数执行之前如何执行呢? 联想到MFC里面的 C**App类的theApp对象,其执行顺序就在main函数之前.道理相通,顺理推下,能够想到:如果在main函数之前声明一个类的全局的对象.那么其执行顺序,根据全局对象的生存期和作用域,肯定先于main函数. 示例如下: class simpleClass { public: simpleClass( ) { cout << "simpleClass construct