零基础逆向工程27_Win32_01_宽字符_MessageBox_win32调试输出
1 多字节字符
ASCII码表:0 ~ 2^7-1
扩展ASCII码表:2^7 ~ 2^8-1
什么是GB2312:1980年,两个字节存储一个汉字;不通用,别国会有乱码。
UCICODE:只有一个字符集;每个字符都是16位宽。
2 C语言中的宽字符
2.1 宽字符的使用
"中"字的编码:
ASCII:d6 d0
UNICODE:4e 2d
char x = '中'; //汇编代码中出现的是d0
wchar_t x1 = '中'; //汇编代码中出现的是d0 d6
wchar_t x1 = L'中'; //告诉编译器我们要使用的是Unicode的那张表; 汇编代码4e 2d
2.2 宽字符串的使用
char x[] = "中国";
//d6 d0 b9 fa 00 使用拓展ASCII编码表 以00(\0)结尾
wchar_t x1[] = L"中国";
//2d 4e fd 56 00 00 使用UNICODE编码表 以00 00(\0\0)结尾
2.3 在控制台打印
char x[] = "中国";
wchar_t x1[] = L"中国";
printf("%s\n",x); //使用控制台默认的编码
wprintf(L"%s\n",x1); //默认使用英文
告诉编译器,使用控制台默认的编码格式
(1) 包含头文件 #include <locale.h>
(2) setlocale(LC_ALL,""); //使用控制台默认的编码
2.4 字符串长度(头文件:#include<string.h>
)
char x[] = "中国";
wchar_t x1[] = L"中国";
strlen(x); //取得多字节字符串中字符长度,不包含 00
wcslen(x1); //取得多字节字符串中字符长度,不包含 00 00
2.5 字符串复制
char x[] = "china";
char x1[] = "123";
strcpy(x,x1);
wchar_t y[] = L"中国";
wchar_t y1[] = L"好";
wcscpy(y,y1);
C语言中的宽字符和多字符
char wchar_t //多字节字符类型 宽字符类型
printf wprintf //打印到控制台函数
strlen wcslen //获取长度
strcpy wcscpy //字符串复制
strcat wcscat //字符串拼接
strcmp wcscmp //字符串比较
strstr wcsstr //字符串查找
3 Win32 API中的宽字符
3.1 什么是Win32 API?有哪些?在哪里?
主要是存放在 C:\WINDOWS\system32 下面所有的dll
3.2 非常重要的几个DLL
Kernel32.dll:最核心的功能模块,比如管理内存、进程和线程相关的函数等.
User32.dll:是Windows用户界面相关应用程序接口,如创建窗口和发送消息等.
GDI32.dll:全称是Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函数
比如要显示一个程序窗口,就调用了其中的函数来画这个窗口
3.3 Win32 API中的宽字符和多字节字符
Windows是使用C语言开发的,Win32 API同时支持宽字符与多字节字符.
(1) 字符类型 | (2) 字符串指针 |
---|---|
char CHAR | PSTR(LPSTR) 指向多字节字符串 |
wchar_t WCHAR | PWSTR(LPWSTR) 指向宽字符串 |
宏 TCHAR | 宏 PTSTR(LPTSTR) |
字符数组赋值
CHAR cha[] = "中国";
WCHAR chw[] = L"中国";
TCHAR cht[] = TEXT("中国");
为字符串指针赋值:
PSTR pszChar = "china"; //多字节字符
PWSTR pszWChar = L"china"; //宽字符
PTSTR pszTChar = TEXT("china"); //如果项目是ASCII的 相当于"china" UNICODE 相当于L"china"
3.4 各种版本的MessageBox
MessageBoxA(0,"内容多字节","标题",MB_OK);
MessageBoxW(0,L"内容宽字节",L"标题",MB_OK);
MessageBox(0,TEXT("根据项目字符集决定"),TEXT("标题"),MB_OK);
Windows提供的API 凡是需要传递字符串参数的函数,都会提供两个版本和一个宏.
4 Win32的入口程序
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
return 0;
}
参数:
hInstance:
表示该程序当前运行的实例句柄,是一个数值标识。当程序在Windows下运行时,它唯一标识运行中的实例(注意,只有运行中的程序实例,才有实例句柄)。一个应用程序可以运行多个实例,每运行一个实例,系统都会给该实例分配一个实例句柄,并通过hInstance参数传递给WinMain函数。
hPrevInstance:
表示当前实例的前一个实例的句柄。通过查看MSDN我们可以知道,在Win32环境下,这个参数总是NULL,即在Win32环境下,这个参数不再起作用。
lpCmdLine:
是一个以空字符结尾的字符串,内容为命令行的参数。
nCmdShow:
指定程序的窗口应该如何显示,例如最大化、最小化、隐藏等。这个参数的值由该程序的调用者所指定,应用程序通常不需要去理会这个参数的值。
5 在Win32程序中打印信息
.h
void __cdecl OutputDebugStringF(const char *format, ...);
#ifdef _DEBUG
#define DbgPrintf OutputDebugStringF
#else
#define DbgPrintf
#endif
.cpp
void __cdecl OutputDebugStringF(const char *format, ...)
{
va_list vlArgs;
char *strBuffer = (char*)GlobalAlloc(GPTR, 4096);
va_start(vlArgs, format);
_vsnprintf(strBuffer, 4096 - 1, format, vlArgs);
va_end(vlArgs);
strcat(strBuffer, "\n");
OutputDebugStringA(strBuffer);
GlobalFree(strBuffer);
return;
}
以后调试win32程序,同样可以使用DbgPrintf()函数来打印测试信息。
6 GetLastError的使用
TCHAR szContent[] = TEXT("内容");
TCHAR szTitle[] = TEXT("标题");
MessageBox((HWND)0,szContent,szTitle,MB_OK);
DWORD errorCode = GetLastError();
可以查看errorCode中的值,查到错误原因(在msdn中查)