X64dbg 2021最新版 中文乱码解决
X64dbg中文乱码解决
X64dbg可以对64位的软件进行反编译,是针对Olldbg只能调试32位软件的改进,使用也比较方便。但由于该软件前端使用QT开发,对中文的解析经常会出现乱码,不能很好解析出中文(经测试发现对GB2312、GBK的字符解析都没问题),使用Strings和x64dbg_tol两款插件也不能解决问题,为此对x64dbg-2021-1-12版进行了修改完善,增加了解析UTF-8及完善了UTF-16(Unicode)的功能,并对CPU dump界面显示方式和寄存器、堆栈标签显示方式进行了修改,同时增加了自动对进程PEB和线程TLB进行注释的功能。
一、源码下载及编译
1、下载development版源码
$ git clone -b development https://hub.fastgit.org/x64dbg/x64dbg.git
进入x64dbg目录下,将.gitmodules内的github.com替换为hub.fastgit.org
然后在x64dbg目录内执行:
git submodule update --init --recursive
下载子目录文件。(使用hub.fastgit.org代替github.com是为了加快下载速度)
2、安装编译环境
下载安装:
qt-opensource-windows-x86-msvc2013_64-5.6.3.exe
qt-opensource-windows-x86-msvc2013-5.6.3.exe
qt-creator-opensource-windows-x86-4.3.1.exe
vs2013sp5
windows_sdk_8.1
qt-vsaddin-msvc2013-2.3.2.vsix
并完成QT_VS_TOOLS的设置(通用设置,略)。
为了调试方便,QT的pro工程使用QT_VS_TOOLS导入解决方案中,不单独使用qt-creater编译。
导入工程选择x64-release版本编译即可成功。(略)
二、UTF-8解析功能实现
在x64dbg\src\dbg\disasm_helper.cpp文件内修改如下函数:
在isunicodestring内对汉字进行严格过滤
extern "C" __declspec(dllexport) bool isunicodestring(const unsigned char* data, int maxlen)
{int len = 0;wchar_t* safebuffer = new wchar_t[maxlen];if(!safebuffer)return false;//修改开始//严格匹配汉字if (((unsigned char)data[0] < 0x34) || ((unsigned char)data[0] > 0x80)){return false;}else if (((unsigned char)data[0] == 0x4D) && ((unsigned char)data[1] > 0xB5)){return false;}//修改结束for(const wchar_t* p = (const wchar_t*)data; *p; len += sizeof(wchar_t), p++){if(len >= maxlen)break;safebuffer[p - (const wchar_t*)data] = *p;}if(len < 2 * sizeof(wchar_t)){delete[] safebuffer;return false;}safebuffer[len / sizeof(wchar_t) - 1] = 0; // Mark the end of stringString data2;WString wdata2;// Convert to and from ANSIdata2 = StringUtils::Utf16ToLocalCp(safebuffer);delete[] safebuffer;if(data2.size() < 2)return false;wdata2 = StringUtils::LocalCpToUtf16(data2);if(wdata2.size() < 2)return false;// Is the data exactly representable in both ANSI and Unicode?if(memcmp(wdata2.c_str(), data, wdata2.size() * sizeof(wchar_t)) != 0)return false;// Filter out bad charsif(!isunicodestring(wdata2))return false;return true;
}
增加utf-8字符串判断函数(此处只检测第一个字符是否为utf-8):通过对软件数据跟踪发现,x64dbg内同时存在三字节的UTF-8和两字节的UTF-8,而两字节的UTF-8软件处理位Unicode编码(软件命名为UTF-16),而对三字节的UTF-8编码没有进行处理,
如图:0000h地址处的 E590就是"启"的两字节UTF-8编码0x90E5,即通常意义的Unicode码。
0xCCh处的E590AF就是启的三字节UTF-8编码0xE590AF。
extern "C" __declspec(dllexport) bool isutf8string(const unsigned char* data, int maxlen)
{int len = 0;char* safebuffer = new char[maxlen];if (!safebuffer)return false;for (const char* p = (const char*)data; *p; len++, p++){if (len >= maxlen)break;safebuffer[p - (const char*)data] = *p;}if (len < 2){delete[] safebuffer;return false;}safebuffer[len] = 0; // Mark the end of stringbool isutf8 = false;//只匹配三字节表示的汉字if (((unsigned char)safebuffer[0] >= 0xE3) && ((unsigned char)safebuffer[0] <= 0xE9)){if (((unsigned char)safebuffer[1] >= 0x80) && ((unsigned char)safebuffer[1] <= 0xBF)){if (((unsigned char)safebuffer[2] >= 0x80) && ((unsigned char)safebuffer[2] <= 0xBF)){isutf8 = true;}else{isutf8 = false;}}else{isutf8 = false;}}else{isutf8 = false;}return isutf8;
}
disasmispossiblestring内增加对utf8字符串的处理
bool disasmispossiblestring(duint addr, STRING_TYPE* type)
{unsigned char data[60];memset(data, 0, sizeof(data));duint bytesRead = 0;if(!MemReadUnsafe(addr, data, sizeof(data), &bytesRead) && bytesRead < 2)return false;if(isasciistring(data, sizeof(data))){if(type)*type = str_ascii;return true;}if(isunicodestring(data, sizeof(data) / 2)){if(type)*type = str_unicode;return true;}//修改开始if (isutf8string(data, sizeof(data) + 1)){if (type)*type = str_utf8;return true;}//修改结束if(type)*type = str_none;return false;
}
disasmgetstringat对三字节UTF-8字符串进行编码转换,并返回
bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode, int maxlen)
{if(type)*type = str_none;if(!MemIsValidReadPtrUnsafe(addr, true) || !disasmispossiblestring(addr))return false;Memory<unsigned char*> data((maxlen + 1) * 2, "disasmgetstringat:data");MemReadUnsafe(addr, data(), (maxlen + 1) * 2); //TODO: use safe version?// Save a few pointer castsauto asciiData = (char*)data();// First check if this was an ASCII only stringif(isasciistring(data(), maxlen)){if(type)*type = str_ascii;// Convert ANSI string to UTF-8std::string asciiData2 = StringUtils::LocalCpToUtf8((const char*)data());memcpy(asciiData, asciiData2.c_str(), min((size_t(maxlen) + 1) * 2, asciiData2.size() + 1));// Escape the stringString escaped = StringUtils::Escape(asciiData);// Copy data back to outgoing parameterstrncpy_s(ascii, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE);return true;}if(isunicodestring(data(), maxlen)){if(type)*type = str_unicode;// Convert UTF-16 string to UTF-8std::string asciiData2 = StringUtils::Utf16ToUtf8((const wchar_t*)data());memcpy(asciiData, asciiData2.c_str(), min((size_t(maxlen) + 1) * 2, asciiData2.size() + 1));// Escape the stringString escaped = StringUtils::Escape(asciiData);// Copy data back to outgoing parameterstrncpy_s(unicode, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE);return true;}//修改开始if (isutf8string(data(), maxlen)){if (type)*type = str_utf8;// Convert UTF-16 string to UTF-8std::string asciiData2 = (const char*)data();memcpy(asciiData, asciiData2.c_str(), min((size_t(maxlen) + 1) * 2, asciiData2.size() + 1));// Escape the stringString escaped = StringUtils::Escape(asciiData);// Copy data back to outgoing parameterstrncpy_s(unicode, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE);return true;}//修改结束return false;
}
disasmgetstringatwrapper处理字符串输出,此处“&L”开头为两字节Unicode(UTF-16)字符,“#F”开头为三字节UTF-8字符
bool disasmgetstringatwrapper(duint addr, char* dest, bool cache)
{if(!MemIsValidReadPtrUnsafe(addr, cache))return false;auto readValidPtr = [cache](duint addr) -> duint{duint addrPtr;if(MemReadUnsafe(addr, &addrPtr, sizeof(addrPtr)) && MemIsValidReadPtrUnsafe(addrPtr, cache))return addrPtr;return 0;};*dest = '\0';char string[MAX_STRING_SIZE];duint addrPtr = readValidPtr(addr);STRING_TYPE strtype;auto possibleUnicode = disasmispossiblestring(addr, &strtype) && strtype == str_unicode;//修改开始-by WangRui 20210107auto possibleUtf8 = disasmispossiblestring(addr, &strtype) && strtype == str_utf8;auto possibleAscii = disasmispossiblestring(addr, &strtype) && strtype == str_ascii;if (possibleAscii) //addrPtr &&possibleAscii{if (disasmgetstringat(addr, &strtype, string, string, MAX_STRING_SIZE - 5)) //addrPtr{if (strtype == str_ascii)sprintf_s(dest, MAX_STRING_SIZE, "\"%s\"", string);else if (strtype == str_unicode)//unicodesprintf_s(dest, MAX_STRING_SIZE, "L\"%s\"", string);else if (strtype == str_utf8)sprintf_s(dest, MAX_STRING_SIZE, "F\"%s\"", string);return true;}}if (possibleUnicode){if (disasmgetstringat(addr, &strtype, string, string, MAX_STRING_SIZE - 4)){if (strtype == str_ascii)sprintf_s(dest, MAX_STRING_SIZE, "&\"%s\"", string);else if (strtype == str_unicode)//unicodesprintf_s(dest, MAX_STRING_SIZE, "&L\"%s\"", string);else if (strtype == str_utf8)sprintf_s(dest, MAX_STRING_SIZE, "&F\"%s\"", string);return true;}}if (possibleUtf8){if (disasmgetstringat(addr, &strtype, string, string, MAX_STRING_SIZE - 4)){if (strtype == str_ascii)sprintf_s(dest, MAX_STRING_SIZE, "#\"%s\"", string);else if (strtype == str_unicode)//unicodesprintf_s(dest, MAX_STRING_SIZE, "#L\"%s\"", string);else if (strtype == str_utf8)sprintf_s(dest, MAX_STRING_SIZE, "#F\"%s\"", string);return true;}}if (addrPtr && !possibleAscii &&!possibleUnicode &&!possibleUtf8){if (disasmgetstringat(addrPtr, &strtype, string, string, MAX_STRING_SIZE - 5)) //addrPtr{if (int(strlen(string)) <= (strtype == str_ascii ? 3 : 2) && readValidPtr(addrPtr)) //addrPtrreturn false;if (strtype == str_ascii)sprintf_s(dest, MAX_STRING_SIZE, "\"%s\"", string);else if (strtype == str_unicode)//unicodesprintf_s(dest, MAX_STRING_SIZE, "L\"%s\"", string);else if (strtype == str_utf8)sprintf_s(dest, MAX_STRING_SIZE, "F\"%s\"", string);return true;}}return false;
}
修改后即可在字符串参考中正确解析处UTF-8字符。
三、界面显示修改
在寄存器及堆栈的标签、备注显示方式中使用“string:module.label”形式,
并增加了PEB和TEB自动注释的功能
及CPU Dump窗口多种编码同时显示功能。
由于只是UI的操作,此处就不贴代码了
附件:
可编译源码 及 x64dbg修改版:
下载地址一:
链接:https://pan.baidu.com/s/1zEy0o_D3HJz1R5kUfKOj-Q
提取码:3jpm
复制这段内容后打开百度网盘手机App,操作更方便哦
下载地址二:
编译后软件:x64dbg_2021_01_12(Modified By 风吹小裤衩(20210329))
软件源码:x64dbg_2021_01_12源码(Modified By 风吹小裤衩(20210329))
不足之处,欢迎报告Bug
X64dbg 2021最新版 中文乱码解决相关推荐
- java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**
原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)-–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...
- pycharm 运行控制台中文乱码解决办法
pycharm 运行控制台中文乱码解决办法
- vs code中文乱码解决方法
修改 1.(安装方法) 2.显示终端输入数据输出结果(完美解决) 3.修改部分:中文乱码解决方法 第一步: 第二步: 1.(安装方法) 转载于: https:blog.csdn.net/qq_4304 ...
- Zabbix 中文乱码解决
Zabbix 中文乱码解决 1.在本地的C:\Windows\Fonts下选择自己喜欢的字体,此处选择黑体(我只测试过宋体,楷体,黑体,幼圆其他中文字体应该都支持) 在C:\Windows\Fonts ...
- Ubuntu10.04下gFtp2.0.19 远程客户端中文乱码解决方法
Ubuntu10.04下gFtp2.0.19 远程客户端中文乱码解决方法如下: 1.打开"gFTP-FTP-属性-常规-远程字符集": 2.将远程字符集设置为:gb2312,gbk ...
- navicat for mysql 显示中文乱码解决办法
navicat for mysql 显示中文乱码解决办法 最近遇到一个问题,用navicat for mysql 打开数据库时全都显示的是乱码(在用程序代码插入数据之前确保字符不是乱码),遇到问题 ...
- python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色)
python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色) 参考文章: (1)python cmd 窗口 中文乱码 解决方法 (附:打印不同颜色) (2)https://www.cnblog ...
- Sublime Text 3中文乱码解决方法以及安装包管理器方法
Sublime Text 3中文乱码解决方法以及安装包管理器方法 参考文章: (1)Sublime Text 3中文乱码解决方法以及安装包管理器方法 (2)https://www.cnblogs.co ...
- axios请求GBK页面中文乱码解决方法
axios请求GBK页面中文乱码解决方法 参考文章: (1)axios请求GBK页面中文乱码解决方法 (2)https://www.cnblogs.com/bjhl/articles/10514038 ...
最新文章
- EigenUbuntu下的配置
- python 慕课课程笔记(一)
- 【Python基础】在pandas中使用pipe()提升代码可读性
- 将Sublime Text3添加到右键菜单中
- ai电磁组属于什么组_RPA+AI 创新案例挑战赛 2020 【专业组】amp;【校园组】优胜名单来也!...
- Java 面试题(3)—— JVM
- Linux中远程文件的传输
- 史上最全MySQL锁机制
- 通过AccessKey调用阿里云CDN接口刷新CDN资源案例
- python导入xlsx转为csv_Python 拆分工作表为单个工作簿
- 第六届华为创新杯编程大赛第二轮(2014.4.29)
- 磁盘加密工具-TrueCrypt
- labview霍夫曼编码_毕业设计 基于LabVIEW的编码的设计与仿真—信源编码
- pano2vr输出的HTML手机可以看吗,Pano2VR怎么导出手机可看, Pano2VR导出手机查看教程...
- win8系统电脑使用技巧的详细介绍--win7w.com
- 海外服务器对外提供业务是否需要ICP许可证?
- 吐血推荐:“四无男”泡良 妞 实战攻略
- qt修改程序图标名称_【Qt开发】更改应用程序图标和任务栏图标
- innerText和innerHTML区别
- 化妆品电商平台数据分析报告
热门文章
- 64位处理器_CAD安装包32位跟64位有什么区别吗?
- 凝思linux操作系统4.2内核版本_国产自主操作系统:凝思磐石安全操作系统
- inpaint 9.1新版3秒去除一切图片中的无关元素
- FPGA linux synplify综合工程的环境搭建
- WSL 错误 System has not been booted with systemd as init system (PID 1). Can‘t operate
- 微信分享默认logo修改
- 新手小白怎么学好PS平面设计?过来人经验总结
- 2018 数学建模 国赛(高教杯)-智能RGV的动态调度策略
- 【解决】小程序|微信公众号授权给第三方平台时报“没有绑定公众号”
- 车载硬盘录像机-从芯片层面来谈嵌入式DVR的发展