WIN32程序挂钩SetLastError,输出错误描述到控制台
WIN32程序挂钩SetLastError,输出错误描述到控制台
作者:徐灵甫
一、窗口模式应用程序(GUI)启用控制台的方法为:
| 步骤 | 方法 |
| 1 启动/关闭控制台 | AllocConsole() FreeConsole() |
| 2 重定向输入/输出 | freopen("CONIN$","r",stdin) freopen("CONOUT$","w",stdout) freopen("CONOUT$","w",stderr) |
| 3 控制台输入/输出 | #include <conio.h> #include <stdio.h> printf(...) scanf(...) system("pause") |
二、挂钩API函数的简单方法为:
1. DEBUG模式下,函数名值为指令“JMP函数体”的地址。指令格式为“E9 □□□□”,附带的参数为四字节表示的转移偏移量。因此“函数名值 + *(DWORD*)((DWORD)函数名值 + 1)”为函数体入口地址。“使用转到反汇编”的功能计算出函数体入口栈指令长度,得出实际入口地址为“函数名值 + *(DWORD*)((DWORD)函数名值 + 1) + 入口栈指令长度”;
2. RELEASE模式下,函数名值直接为函数体的入口地址。使用“转到反汇编”的功能计算出函数体除退出指令外的指令长度,得出函数出口地址为“函数名 + 指令长度”,API函数正是这种模式;
3. 使用“::WriteProcessMemory(::GetCurrentProcess(), API函数出口地址...)”的方法在API函数上挂钩以下调用:
| 序号 | 说明 | 指令 | 参数值 |
| 1 | 调用挂钩函数 | E8 □□□□ | 挂钩函数体实际入口地址 |
| 2 | 退出 | C2 □□ | 函数参数总长度,用于恢复栈的状态 |
三、挂钩API函数SetLastError,并输出错误描述到控制台的范例
#include <stdio.h>
#include <windows.h>
void hook_SetLastError()//为简化调用挂钩函数时的栈操作,挂钩函数无参数和返回值。
{
if (::GetLastError())
{
LPVOID lpMsgBuf = 0;
if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
0, ::GetLastError(), LANG_USER_DEFAULT, (LPTSTR) &lpMsgBuf, 0, 0))
{
::printf("ERROR: %d %s", ::GetLastError(), (LPCSTR)lpMsgBuf);
::LocalFree(lpMsgBuf);
}
}
} int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
unsigned char setup_SetLastError[8] = {0xE8, 0, 0, 0, 0, 0xC2, 4, 0};
#ifdef _DEBUG
*(unsigned int*)(setup_SetLastError + 1) = (unsigned int)hook_SetLastError +
*(unsigned int*)((unsigned char*)hook_SetLastError + 1) - (unsigned int)SetLastError - 18;
#else
*(unsigned int*)(setup_SetLastError + 1) = (unsigned int)hook_SetLastError -
(unsigned int)SetLastError - 23;
#endif
::WriteProcessMemory(::GetCurrentProcess(), (LPVOID)((unsigned int)::SetLastError + 18),
setup_SetLastError, 8, new SIZE_T);
::AllocConsole();
::freopen("CONIN$", "r", stdin);
::freopen("CONOUT$", "w", stdout); //此处添加自己的代码
::WriteProcessMemory(::GetCurrentProcess(), (LPVOID)((unsigned int)::SetLastError + 18),
setup_SetLastError + 5, 3, new SIZE_T);
::system("pause");
return 0;
}
(全文完)
http://blog.csdn.net/jiangxinyu/article/details/5386000
WIN32程序挂钩SetLastError,输出错误描述到控制台的更多相关文章
- 一起学libcef--搭建自己的libcef运行环境(Win32程序,错误C2220解决方案)
转自 http://blog.csdn.net/wangshubo1989/article/details/50180413 现在就来讲讲如何在自己的win32程序中搭建libcef运行环境. 首先就 ...
- 关于Oracle报“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误
关于Oracle报“ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务”错误原因:listener.ora中没有指定监听服务器名. 如下是解决思路: 尝试1.通过重启服务的方式启动数 ...
- 引用 运行asp.net程序时候,编译器错误消息: CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET\Fra
引用 运行asp.net程序时候,编译器错误消息: CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary A ...
- ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的SID等错误解决方法
程序连接orarle报ORA-12505错误 一.异常{ ORA-12505, TNS:listener does not currently know of SID given in connect ...
- 第二章--Win32程序运行原理 (部分概念及代码讲解)
学习<Windows程序设计>记录 概念贴士: 1. 每个进程都有赋予它自己的私有地址空间.当进程内的线程运行时,该线程仅仅能够访问属于它的进程的内存,而属于其他进程的内存被屏蔽了起来,不 ...
- 控制台程序的中文输出乱码问题(export LC_CTYPE=zh_CN.GBK,或者修改/etc/sysconfig/i18n为zh_CN.GBK。使用setlocale(LC_CTYPE, "");会使用默认办法。编译器会将源码做转换成Unicode格式,或者指定gcc的输入文件的编码参数-finput-charset=GBK。Linux下应该用wprintf(L"%ls/n",wstr))
今天发现用securecrt登陆时,gcc编译出错时会出现乱码,但直接在主机的窗口界面下用Shell编译却没有乱码.查看了一下当时的错误描述,发现它的引号是中文引号,导致在SecureCRT中显示出错 ...
- 什么是消息循环,一个简单的win32程序如何运行?
预备知识 1.什么是句柄? (HANDLE) 在win32编程中有各种句柄,那么什么是句柄呢? #define DECLARE_HANDLE(name) struct name##_ { int un ...
- (转)ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法
早上同事用PL/SQL连接虚拟机中的Oracle数据库,发现又报了"ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务"错误,帮其解决后,发现很多人遇到过这样的问 ...
- ZeroMQ接口函数之 :zmq_strerror - 获取ZMQ错误描述字符串
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_strerror zmq_strerror(3) ØMQ Manual - ØMQ/4.1.0 Name zmq_ ...
随机推荐
- Mongodb快速入门之使用Java操作Mongodb
[IT168 专稿]在上一篇文章中,我们学习了Mongodb的安装和初步使用,在本文中,将学习如何使用Java去编程实现对Mongodb的操作. HelloWorld程序 学习任何程序的第一步,都是编 ...
- Struts2自己定义拦截器实例—登陆权限验证
版本号:struts2.1.6 此实例实现功能:用户须要指定username登陆,登陆成功进入对应页面运行操作,否则返回到登陆页面进行登陆,当直接訪问操作页面(登陆后才干訪问的页面)时则不同意,须返回 ...
- HDU - 4815 Little Tiger vs. Deep Monkey (长春赛区C题)
题意:有A,B两个人.n道题目.每题有相应的分数.B答对题目的概率是0.5.求A不输给B的概率不小于P要拿的最低分数 思路:DP,dp[i][j]来表示B答了前i题后分数为j的概率,,然后通过B的概率 ...
- [连载]JavaScript讲义(03)--- JavaScript面向对象编程
- jni那点事
今天说一下在jni开发中常另新手迷惑的JNIEnv这个东西 比如一个c语言的函数 JNIEXPORT jstring JNICALL Java_com_mmmmar_nativethread_Main ...
- C#自定义事件:属性改变引发事件示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- VB指针 与CopyMemory
体会ByVal和ByRef Dim k As Long CopyMemory ByVal VarPtr(k), 40000, 4 等同于k=40000:从保存常数40000(缺省ByRef)的临时变量 ...
- 如何做高大上的网站布局 -------------------->>转至(卧牛SEO/武汉SEO http://blog.sina.com.cn/zhengkangseo )
SEO开始做,最重要的是网站布局,一个网站布局决定了用户在网站的停留时间,在网站中放入用户想要的内容之外,更重要的是要让用户看到网站之后,一目了然,视觉和感官上良好的体验.那新手该如何做网站布局呢? ...
- 《scraping with python》
记得刚开始学习python时就觉得爬虫特别神奇,特别叼,但是网上的中文资料大都局限于爬取静态的页面,涉及到JavaScript的以及验证码的就很少了,[当时还并不习惯直接找外文资料]就这样止步于设计其 ...
- 从一个SVN下载的导入另一个SVN里面
如果项目是你从个一个SVN下载的,你想存入另一个SVN里面 那么问题来了 你用eclipse的team的时候会发现没有Team share 这个选项,那么就等于是没有上传的选项了 解决办法,把项目删掉 ...