破解 Windows 程序技巧(1)

/ns/hk/crack/data/20020822033522.htm



Dear All,

u8016028@cc.nctu.edu.tw 是谁我不知道, 不过他曾让我感动的久久不能自已. 我曾承
诺当我在破解 windows 软体有心得时要 post 上来. 最近我相信有些突破, 能破解
dos 软体的高手嘛, 在不懂 windows SDK 时, 也可以轻松破掉. 感谢很多人帮我 post
上来的东西做贝塔测试, 虽然经常有点小问题, 但整个架构应该让大家轻松很多. 不过
这方法需要 soft-ice for windows.

型态一--可注册 windows 软体.
特徵是当未注册时, 一进去会有延迟画面, 可能有时效限制(30天後不能用之类),
在某个地方有个注册功能, 打开之後是个对话框, 要求输入密码, 有时还有姓名和公司
名称.

程式如何判断注册与否?
通常两种方式:
1. 在程式码的某一处, 藏有 "注册印记". 如00表未注册, 01为已注册. 当然也有
很奇怪的数字, 如 f8 03 表已注册.
2. install 时程式开 *.ini, 或写入 win.ini, 把资料存在那里.

程式如何保护:
最通常是用你的name当作key, 经过复杂演算法, 算出密码.

程式流程:
...
...
...
get register data /* 可能从*.ini 念出, 或从程式某一段读出某一byte */
if registered /* registered 判断可能是一行指令, 也可以是副程式 */
main_program;
else
if date_expired
end_program;
else
show_unregistered_screen;
main_program;
...
...
main_program()
...
...

注册处理:

1. 当输入name, company, password 後, 立即比对, 正确的话立即做注册处理, 以後
再也不判断, 不正确要求再输入. 不输入 name 的话, 保持 shareware 版.
2. 同1, 但以後一执行程式还是会判断.
3. 输入时不比对, 只写入资料於 *.ini, 程式执行时再比对.

如何判断追踪时我们身在何处:

在dos程式, 进入debuger 後, 只要我们不进入 int 一定留在程式里. 在 windows
call back 方式下, cpu 在程式和系统里跑来跑去, 关於这点我曾post 过, 或请参阅
相关书籍. 我们如何知道现在在系统还是程式中呢? winice 在下面3/4处有一条横线,
中间有 ***.1, ***.10 之类的东西, 以程式为 abc.exe 为例, 如果是 abc.5, 表示在
abc.exe 里的第5个模组(或副程式中), 系统主要有三个模组 user, kernel, gdi, 所以
看到 user.119 这是在系统中, 别被 user 这个字骗了. 如果你不能肯定, 可用 bc4
所附 tdump.exe 来看 (这是dos程式), export 的就是非系统模组.


如何破解:

在 dos版输入字串时, 程式可能呼叫 int 21, int 16, int 9. 通常我们拦 int 16.
但如果程式呼叫 int 21, 我们拦 int 16 会不会不妥当呢? 不会! 我们多 P 几次, 直
到 iret 就从系统回到程式了. 记得这一点, 多P 几次到 iret 就从系统回来了.

在讲破解捷径前, 我们先作个小实验. 请先进任一程式(这里以abc.exe为例)的注册
画面, 输入密码为 121345, ^D 叫出 winice, 看看我们在那里, 如是 user, kernel, gd.
则按 ^D 回来, 再按一次 ^D, 直到模组为 vmm 为止. 好现在我们打入 winice 指令:
s ds:0000 l ffffff '121345' /* 6 个 f 比较稳 */
通常会在 30:????? 找到, 我们当作是 30:7777 好了.
打入,
bpm 30:7777 rw
按 ^d 回来, 再按下注册画面的 <ok>. winice 会因这个中断点的设置而停住一个mov
指令, 看一下, 你会发现在 user.??? 中. 我们多 P几次, 经过几个retf 会回到
abc.??? 中. 再以 dos 程式为例, vmm 犹如 int 16, user 是 int 21, 经过几个 retf
回到 abc.exe 即为经过 iret 回到dos程式. 在dos 里回来之後上一行一定是 int 21,
在 windows 下是什麽呢? 我履试不爽-------GetDlgItemText.
~~~~~~~~~~~~~~
GetDlgItemText 的用法请用 bc4 的 API help 查询. 前面几个 push 就是参数位址,
取回来的就是我们输入的 '121345'.
通常程式写法如下:
...
...
push ****
GetDlgItemText /* 取回密码 */
...
...
push
GetDlgItemText /* 取回名字 */
...
...
push
GetDlgItemText /* 取回公司 */
call **** /* 绝大部份是短程呼叫 */
cmp ax,00
jnz ****
...
...
眼尖的人一定看懂了, call **** 就是比对程式, 只要把 jnz 改掉就 OK. 当然也会有变
型, call **** 只是看看name, company 是不是空白, 空白的话保持 shareware, 非空白
才跑去比对, 所以後面还会有另一个
call ****
cmp ax,00
jnz ****
如果你能解 dos 程式, 这些都难不倒才对.
所以捷径如下:
1.打开注册画面.
2.^D 到 winice, 打上 bpx getdlgitemtext
3. ^d 回来, 输入每一栏 name , company, password, 按<OK>.
4.winice 会停在 getdlgitem 的第一行, 多 p 几次, 经过 retf 回到程式.
5.把jnz 改掉.

上面方法适合注册程序1.的情形. 至於2, 在运气好一点, 你可追进 call **** 中, 把
最後ax 值改掉, 因为一进程式的比对可能也是叫这里. 运气不好或是3的情形, 则再看
一次程式流程

get register data
if registered
...
...
get register data 通常从 *.ini 念入, 如是写上注册印记的, 在上面注册画面後,
我们就已经破掉. ini 是从那个指令读入呢? 试试看
bpx getprivateprofileint 和 /* 用bc4 API reference 看一下用法 */
bpx getprivateprofilestring
程式通常如下:

push
getprivateprofileint /* 取得 *.ini number= 这一栏 */
...
...
push
getprivateprofilestring /* 取得 *.ini name= 这一栏 */
...
...
push
getprivateprofilestring /* 取得 *.ini company - 这一栏 */
call ****
cmp ax, 00
jnz

还有一个更稳的方法, 因为未注册一定有干扰画面, 所谓干扰画面其实是一个对话框,
windows 开对话框的方法有7,8种, 请把 bc4 api reference dialog boxes 打开来看
有 dialogbox, createdialogbox, createdialogindirect......
bpx dialogbox 不行, 再
pbx createdialogbox 不行, 再
...
...
一路卯下, 总会命中. 然後一路 p 下来, 经过retf 回到程式, 比较一下前後 cmp 指令
, 两三下就解掉.

效果:

破解後任何人都可输入自己名字再随便输个密码成为注册版. 坏处是检查点多几来
经常有小问题.

型态二--不能注册 windows 软体.
我们能做的只是跳过干扰画面和日期比对, 用上述 bpx dialogbox 方式, 可以解掉.

基本上, 这些都是原则, 程式设计师经常弄些小陷阱, 不过无伤大碍, 当别人告诉你这破
解法这个不能用, 那个不能用时, 再看一次, 多改几码, 照样解掉.

如果那位大哥想和我讨论这个破解法, 是不是能请你动手试之後, 拿特定程式来讨论比
较好. 另外, 敝人想趁 win95 流行前, 弄些 os2 破解, 不知有没有人能教我:)

-- ellery