本帖最后由 javacafe 于 2019-3-14 21:59 编辑
今天刷网看到 Sublime Text 3.2 新版本发出, 突然想起前几天美国安全部发布的逆向工具Ghidra,还没怎么试用,所以就想既然闲着没事何不用
练练手,想到此,说干就干。
注:Ghidra 要求使用JDK 11
1. 运行Ghidra,创建一个工程文件,然后File --> Import File 导入要逆向的文件,也就是sublime_text.exe,导入时会提示导入选择项,基本不用管直接导入。
2. 然后当前工程页面直接点击导入的sublime_text.exe文件,或是选中sublime_text.exe按右键选择“Open With” 中的Code Browser打开也可。
3. 等Ghidra分析完成,然后选择Windows菜单中的 Defined String 查看所有字符串,在字符串窗口下方的Filter输入框中输入 “license”,列出了所有
带license的字符串。在sublime中输入注册码不正确时的提示信息是“That license key doesn't appear to be valid. Please check that you。。。”,所以
选择这个字符串。
4. 在中间的机器码窗口直接定位到了该字符串的代码位置,然后直接点击其右上角的XREF地址。
在转到引用地址的代码后发现还是引用,继续点XREF,然后看到像是正常逻辑的代码。
然后点菜单工具栏的"Cf"样子的按纽或是按Ctrl+E,显示伪代码窗口
5. 简单查看伪代码
[C] 纯文本查看 复制代码
/* WARNING: Could not reconcile some variable overlaps */
void UndefinedFunction_1400911a8(longlong lParm1)
{
longlong lVar1;
longlong lVar2;
char cVar3;
int iVar4;
HANDLE hObject;
undefined8 ****ppppuVar5;
undefined8 ****ppppuVar6;
undefined auStack224 [32];
int iStack192;
undefined8 ***pppuStack184;
undefined auStack176 [16];
undefined auStack160 [16];
undefined uStack144;
undefined auStack128 [16];
undefined8 ****appppuStack112 [2];
longlong lStack96;
ulonglong uStack88;
int iStack76;
undefined8 uStack72;
uStack72 = 0xfffffffffffffffe;
lVar1 = *(longlong *)(lParm1 + 8);
FUN_14035762e(*(undefined8 *)(*(longlong *)(*(longlong *)(lVar1 + 0x260) + 0x130) + 0x6f8),
&pppuStack184);
FUN_14030c5ca(appppuStack112,&pppuStack184);
FUN_14001f19e(&pppuStack184);
pppuStack184 = (undefined **)(((ulonglong)pppuStack184 >> 0x10 & 0xffff) << 0x10);
auStack160 = pslldq(ZEXT816(0xf),8);
auStack176[0] = 0;
uStack144 = 0;
auStack128 = auStack160;
FUN_14008f1a6(*(undefined8 *)(lVar1 + 0x250),&pppuStack184);
FUN_14008ee90(&pppuStack184);
if (lStack96 == 0) {
FUN_14008ef8d(&pppuStack184);
ppppuVar6 = &pppuStack184;
if (0xf < auStack160._0_8_) {
ppppuVar6 = (undefined8 ****)pppuStack184;
}
FUN_1400eb512(ppppuVar6);
FUN_140005858(&pppuStack184);
}
else {
lVar2 = *(longlong *)(lVar1 + 0x250);
iVar4 = FUN_14008f5cc(appppuStack112,lVar2 + 8,lVar2 + 4,&iStack76,lVar2 + 1);
lVar2 = *(longlong *)(lVar1 + 0x250);
*(bool *)lVar2 = iVar4 == 1;
if (iVar4 == 1) {
FUN_140005f36(lVar2 + 0x28,appppuStack112);
FUN_140006ab8(auStack224,appppuStack112);
auStack128 = (undefined [16])0x0 << 0x40;
iStack192 = iStack76;
pppuStack184 = &PTR_LAB_140563708;
FUN_14000ffca(auStack176,auStack224);
auStack128 = CONCAT88(auStack128._8_8_,&pppuStack184);
FUN_140005858(auStack224);
FUN_140189b75(&pppuStack184,120000);
FUN_140009c86(&pppuStack184);
FUN_14008eebe(appppuStack112);
FUN_14008ef8d(&pppuStack184);
ppppuVar6 = appppuStack112;
if (0xf < uStack88) {
ppppuVar6 = appppuStack112[0];
}
ppppuVar5 = &pppuStack184;
if (0xf < auStack160._0_8_) {
ppppuVar5 = (undefined8 ****)pppuStack184;
}
cVar3 = FUN_1400eb174(ppppuVar5,ppppuVar6,lStack96,1);
FUN_140005858(&pppuStack184);
if (cVar3 == 0) {
FUN_1400f7e6e(&DAT_140787ba0,0x166dca7e8 - DAT_1407530a0,0);
}
hObject = (HANDLE)FUN_1400f5754(&LAB_14008f1df,(longlong)iStack76);
CloseHandle(hObject);
if (*(char *)(*(longlong *)(lVar1 + 0x250) + 1) == 0) {
FUN_1400f7e6e(&DAT_140787ba0,0x166dca8cc - DAT_1407530a0,0);
//"Thanks for purchasing!"
}
else {
FUN_1400f7e6e(&DAT_140787ba0,0x166dca892 - DAT_1407530a0,0);
// Hello! Thanks for trying out Sublime Text 3!\n\nSublime Text 3 is a paidupgrade from Sublime Text 2, and your license key is for Sublime Text2.\n\nWould you like to upgrade your license now?
} }
else {
if (iVar4 == 4) {
FUN_1400f7e6e(&DAT_140787ba0,0x166dca8f6 - DAT_1407530a0,0);
//That license key has been invalidated, due to being shared.\n\nPlease [url=mailto:emailsales@sublimetext.com]emailsales@sublimetext.com[/url] to get your license key reissued.
}
else {
if (iVar4 == 3) {
FUN_1400f7e6e(&DAT_140787ba0,0x166dca8e8 - DAT_1407530a0,0);
// That license key is no longer valid.
}
else {
if (iVar4 == 2) {
FUN_1400f7e6e(&DAT_140787ba0,0x166dca8da - DAT_1407530a0,0);
//That license key doesn't appear to be valid. Please check that you have entered all lines from the license key, including the BEGIN LICENSE and END LICENSE lines.
}
}
}
}
}
if (*(longlong *)(lVar1 + 0x2b0) != 0) {
FUN_140009cda(lVar1 + 0x278);
}
(**(code **)(**(longlong **)(lVar1 + 0x28) + 0x18))();
FUN_140005858(appppuStack112);
return;
}
6. 通过上面的代码分析,基本上认为 FUN_14008f5cc 是个关键方法,该方法值返回“1”代表注册成功。
[C] 纯文本查看 复制代码
iVar4 = FUN_14008f5cc(appppuStack112,lVar2 + 8,lVar2 + 4,&iStack76,lVar2 + 1);
lVar2 = *(longlong *)(lVar1 + 0x250);
*(bool *)lVar2 = iVar4 == 1;
if (iVar4 == 1) {
。。。
7. 然后点击FUN_14008f5cc转到该方法的代码,看上去是一堆计算,看着头大。
所以决定直接在函数开始修改为返回eax=1,Ghidra可以直接在代码窗口进行Patch。在需要patch的指令位置,点右键选择Patch Instruction即可。
8. 用Hex工具修改sublime_text.exe,运行,测试注册,输入任意字符,提示成功。
使用感触:因为只是简单使用,最大的感触是Ghidra的分析功能还是挺强大的,XREF比较到位,从定位license串到找到具体的注册信息计算代码就点两下鼠标就到了。
小白的简单试手,高手轻拍。
[ 由于国内PackageControl.io被墙,所以大家可使用 https://github.com/HBLong/channel_v3_daily 这个镜像下载插件]
|