codeshif 发表于 2022-3-23 03:03

GeekUninstall的Pro版本UninstallTool-XX过程

本帖最后由 codeshif 于 2022-3-24 02:27 编辑

前言:小生是个小白,以下内容如有过错,还望各位高手指点。

## 1、PEID查无壳

不管是PEID还是什么查壳软件,或者直接OD分析,确实无壳。



未注册会有这种状态和提示:



关于和退出提示









## 2、OD

经过分析了整体过程,比如使用了API Monitor,但是最后找到了一个非常好用的办法,如下:

首先查看分析字符串,**您也可以使用【中文搜索引擎】,ASCII**


然后发现有一些关键词:



我们根据下面的“IsRegistered”双击进入,并按F2下断点,运行程序



**会有多次断点被断下,每次断下来之后**(应该是多次用到这个函数验证),该处是个函数内部,

程序是在此处判断是否已注册,并将返回值返回(函数返回值保存在EAX中);

按CTRL+F9(执行到返回),再按F8来到这里:



**EAX是刚才函数的返回值,cmp判断返回值是否为3,下面接了个jnz跳转,**自然我们就可以**在jnz这里下手,将其修改为jz**,使跳转不成立,(此处埋下伏笔:如果返回值eax为0x3是否直接成功?)

然后保存文件,测试即可。





此时,**该软件已无提示信息,软件菜单和文件菜单也没有需要注册字样**,关于如图所示:



关闭软件时,也没有退出提示弹窗了,至此过程结束。



## 3、判断函数



刚才很明显我们改变了一个跳转,**还记得跳转前的cmp eax, 0x3吗?这个判断上面是个call函数**

此函数多次被断下,**那么一定与注册检测有关系,**

我们是否可以**通过修改函数内部返回值也可以实现这个功能呢?**来试试!

我们依然来到断点处:

00419A79|.68 B8006100   push Uninstal.006100B8                   ;IsRegistered

代码如下,**太乱没关系,后面有IDA:**

```assembly
00419A76/$53            push ebx
00419A77|.56            push esi
00419A78|.57            push edi
00419A79|.68 B8006100   push Uninstal.006100B8                   ;IsRegistered
00419A7E|.8BF1          mov esi,ecx
00419A80|.33DB          xor ebx,ebx
00419A82|.E8 88FCFFFF   call Uninstal.0041970F
00419A87|.59            pop ecx                                  ;002025E0
00419A88|.8BF8          mov edi,eax
00419A8A|.8BCE          mov ecx,esi
00419A8C|.57            push edi
00419A8D|.E8 5FFEFFFF   call Uninstal.004198F1
00419A92|.8BF0          mov esi,eax
00419A94|.85F6          test esi,esi
00419A96|.74 0E         je short Uninstal.00419AA6
00419A98|.68 C8006100   push Uninstal.006100C8                   ;result
00419A9D|.8BCE          mov ecx,esi
00419A9F|.E8 7A030000   call Uninstal.00419E1E
00419AA4|.8BD8          mov ebx,eax
00419AA6|>85FF          test edi,edi
00419AA8|.74 09         je short Uninstal.00419AB3
00419AAA|.8B17          mov edx,dword ptr ds:               ;Uninstal.0060FE48
00419AAC|.8BCF          mov ecx,edi
00419AAE|.6A 01         push 0x1
00419AB0|.FF52 3C       call dword ptr ds:
00419AB3|>85F6          test esi,esi
00419AB5|.74 09         je short Uninstal.00419AC0
00419AB7|.8B06          mov eax,dword ptr ds:               ;Uninstal.0060FE48
00419AB9|.8BCE          mov ecx,esi
00419ABB|.6A 01         push 0x1
00419ABD|.FF50 3C       call dword ptr ds:
00419AC0|>5F            pop edi                                  ;002025E0
00419AC1|.5E            pop esi                                  ;002025E0
00419AC2|.8BC3          mov eax,ebx
00419AC4|.5B            pop ebx                                  ;002025E0
00419AC5\.C3            retn
```



**然后打开IDA查看伪代码:**

```c
int sub_419A76()
{
int v0; // ebx@1
int v1; // edi@1
int v2; // esi@1

//v0为返回值
v0 = 0;
v1 = sub_41970F("IsRegistered");
v2 = sub_4198F1(v1);
if ( v2 )
    //此处修改过v0
    v0 = sub_419E1E("result");
if ( v1 )
    (*(void (__thiscall **)(int, signed int))(*(_DWORD *)v1 + 60))(v1, 1);
if ( v2 )
    (*(void (__thiscall **)(int, signed int))(*(_DWORD *)v2 + 60))(v2, 1);
return v0;
}
```

可以看见**v0就是返回值,初始化时等于0**,在

```c
if ( v2 )
    v0 = sub_419E1E("result");
```

这里修改过,我们在OD(老崩溃,所以用了x32_dbg,和OD一样)跟过去后,

发现**v0 = sub_419E1E("result");**这个函数的**返回值依然是0**。



唯一可以改变返回值v0的位置就是:

```c
if ( v2 )
    v0 = sub_419E1E("result");
```

那么我们将**v0修改为0x3会如何?**修改为0x3的原因是因为之前的判断,**cmp eax,0x3。**

那么想个办法,让eax保持为0x3即可。



因为mov eax, 0x3需要5字节,为了节省字节,所以这里使用的是

**先push 0x3,再pop eax**,所以改动如下:

```assembly
...
00419A9 | E8 7A 03 00 00      | call uninstalltool.419E1E          |
;00419AA | 8B D8               | mov ebx,eax                        |
00419AA | 6A 03               | push 3                           | <----
00419AA | 85 FF               | test edi,edi                     |
00419AA | 74 09               | je uninstalltool.419AB3            |
00419AA | 8B 17               | mov edx,dword ptr ds:         |
00419AA | 8B CF               | mov ecx,edi                        |
00419AA | 6A 01               | push 1                           |
00419AB | FF 52 3C            | call dword ptr ds:         |
00419AB | 85 F6               | test esi,esi                     |
00419AB | 74 09               | je uninstalltool.419AC0            |
00419AB | 8B 06               | mov eax,dword ptr ds:         |
00419AB | 8B CE               | mov ecx,esi                        |
00419AB | 6A 01               | push 1                           |
00419AB | FF 50 3C            | call dword ptr ds:         |
;00419AC | 5F                  | pop edi                            |
;00419AC | 5E                  | pop esi                            |
;00419AC | 8B C3               | mov eax,ebx                        |
;00419AC | 5B                  | pop ebx                            |
;00419AC | C3                  | ret                              |
00419AC | 58                  | pop eax                            | <----
00419AC | 5F                  | pop edi                            | <----
00419AC | 5E                  | pop esi                            | <----
00419AC | 90                  | nop                              | <----
00419AC | 5B                  | pop ebx                            |
00419AC | C3                  | ret                              |
...
```



## 4、最终效果如下




## 5、补充:x64位处理



有楼下朋友说x64搜索不到字符串或者疑似的问题,我们接着弄一下x64的,x64下请使用x64dbg。

这里注意:根据个人分析,**x64位程序有些区别:**

**1、程序(UninstallTool.exe)启动后,会运行UninstallToolHelper.exe**(根据x64 API Monitor)



**2、UninstallToolHelper.exe该进程用于第二次启动UninstallTool.exe(个人推理,没检测到)**

所以,我们**不能直接将UninstallTool.exe直接载入到x64dbg**,因为主线程会自动退出(**RtlExitUserThread**)。



我们先运行程序,然后使用x64dbg附加该进程,**如果您找不到被调试的进程,请使用管理员方式打开x64dbg**,就可以看到了。





附加后,点击符号,找到uninstalltool.exe,右键在反汇编中转到



然后也是搜索字符串:**IsRegistered**







可以看到和x86代码一样,只是64位寄存器了,

这里和x86调用的函数有些变化,不过大概还是能够找到位置:



注意:这里我尝试过直接将**call uninstalltool.140232C78**修改为**mov eax,3**,结果是不行!!程序会崩溃,因为该call函数中被调用了更多功能。

所以这里我找了一块空白区域,CTRL+B搜索0000000



随便找了一块空间,当然了此处的区段是可执行的





好了,直接从原来的地方跳过来,修改返回值,再调回去即可:









此时,我们回到软件,直接点击帮助,关于我们查看





打补丁保存!





运行查看:





完工!





##感谢各位看官老爷!

###此处是原文件,大家可以试试。



x86:
x64:

当然了您也可以直接去官网下载,https://crystalidea.com/uninstall-tool/download
所有资料下载:https://wwm.lanzoub.com/illgZ01y4cpc

liruishan1995 发表于 2023-3-4 16:52

这软件无法扫描卸载非安装的那种软件,必须是安装的才行,得有安装目录,像有些免安装的软件就不行了。HiBitUninstaller就可以在工具里手动选择软件目录和文件扫描残留卸载

喵筱曦 发表于 2022-3-29 20:22

64位的 将 call uninstalltool.140232C78 修改为 mov eax,3 直接打补丁就可以了,没有崩溃

hnxwk 发表于 2022-3-23 19:14

本帖最后由 hnxwk 于 2022-3-23 19:27 编辑

将00419A9F|.E8 7A030000   call Uninstal.00419E1E修改为mov eax,03就可让eax最后保持为0x3。不需要修改那么多。

伟大的卓哥 发表于 2022-3-23 13:14

可惜是32位的。

SPG.hecyou 发表于 2022-3-23 13:54

来学习,感谢分享!

桴止 发表于 2022-3-23 13:56

膜拜大佬,学习一波

freebsdpf 发表于 2022-3-23 17:02

本帖最后由 freebsdpf 于 2022-3-23 17:08 编辑

64位的找不到 字符串了

hnxwk 发表于 2022-3-23 19:15

freebsdpf 发表于 2022-3-23 17:02
64位的找不到 字符串了

可以找到的

freebsdpf 发表于 2022-3-23 19:24

hnxwk 发表于 2022-3-23 19:15
可以找到的

恩 找到了不过返回的位置   64位的不知道是那里

martin313 发表于 2022-3-23 19:33

这里也有介绍,同款的:https://www.52pojie.cn/thread-1606492-1-1.html

zouxin 发表于 2022-3-23 20:38

感谢分享
页: [1] 2 3 4 5
查看完整版本: GeekUninstall的Pro版本UninstallTool-XX过程