⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows

📁 一套关于加解密的文件
💻
字号:

--------------------------
作者:+ORC
中文翻译:JimTyan
第九课(第一部分)如何拆解WINDOWS程序
---------------------------------------
[Winformant][Snap32]
---------------------------------------
[DATA_CONSTRAINT]数据约束性的秘诀-[WINFORMANT4]
为了向你们演示一个好的小技巧,我选择了一个很老的WIN3.1程序
(WIN4MANT.EXE,562271字节,1.10版,作者:JosephB.Albanese,你可以用通
常的搜索工具在网上找到它,在本课的最后,我会叫你如何做)。这个小技巧在
拆解PASSWORD加密的程序时的确管用,这就是[data_constraint](数据约束性
)。正如你已经知道了的,在大多数加密程式中,那个真正的、正确的注册码
或PASSWORD会于某个时刻出现在内存中。当然它出现的位置是不定的,但多数情
况下它会在一个范围之内,即存放用户输入的内存地址±0X90字节的地方。这是
由于加密者所用工具内部的一个WINDOWS数据传输的约束条件....但是这种用法
肯定要消失...特别是我写了这篇教程之后:=)
[WINFORMANT之拆解]
这个程序本身是蹩脚的,我怀疑你会不会用它...尽管如此,它奇怪的(也是相
当希罕的)“失效”模式使我们对它很感兴趣:如果你觉得需要,你可以立刻取
消注册。这个特点对那些想观察有效和无效PASSWORD算法的人来说是非常有用的,
用不着每次都重装一遍以便删除有效的密码。因为我们是做练习,所以选择这种
具有“可逆”保护特性(少见)或者可以注册上亿次的程序(比较常见)。那些
把有效注册信息保存在*.INI或其它特定文件中的程序也符合我们的要求:你只
要改变几行就可以取消注册。本课要讲的秘诀——数据约束性(data_constraint),
或者“密码相邻性(passwordproximity)”的依据就是加密者在编程的时候要
留意保护功能是否“工作”。他必须“看到”用户输入的数字、用户输入转换
结果和真正密码(用我们的行话就是"Bingo")之间的关系。这种联系必须经常
地检查以调试这些代码。通常它们会共同位于一个小的堆栈区域,使得它们可以
^^^^
在同一个WATCH窗口中看到。所以在大多数情况下,真正的密码会在离保存用户输
^^^^^^
入处不远的地方露出马脚来。
让我们开始:
*启动Winice,然后运行Winformant
*在HELP中选择REGISTRATION
*在Registrant下填入"+ORC+ORC",ActivationCode中填入"12121212"。
CTRL+D;切换到WINICE
∶task;让我们看看这些垃圾的名字
TaskNameSS:SPStackTopStackBotStackLowTaskDBhQueueEvents
WINWORD1AD7:85F24A52867075321247122F0000
PROGMAN1737:200A093620701392066F07F70000
DISKOMAT*2C5F:66341D3C6AC651922CB72C9F0000
∶hwndDISKOMAT;那个窗口获取输入?
WinHandleHqueueQOwnerClassNameWindowProcedure
0EB4(0)2C9FDISKOMAT#3276904A7:9E6B
0F34(1)2C9FDISKOMAT#32768USER!BEAR306
365C(1)2C9FDISKOMAT#327702C3F:0BC6
36BC(2)2C9FDISKOMATButton2C3F:1CEA
3710(2)2C9FDISKOMATEdit2C3F:24BE
...还有很多无关的窗口。
让我们来研究代码,这里有关的窗口显然是(以后会讲到)第一个"Edit"。
∶bmsg3710wm_gettext;设定断点
CTRL+D;运行直到中断
BreakDuetoBMSG3710WM_GETTEXTC=01
Hwnd=3710wParam=0050lParam=2C5F629Amsg=000DWM_GETTEXT
2C3F:000024BEB82F2CMOVAX,2C2F
这样我们找到正确的位置了(以后还会有更多)。让我们多检查几个地方:看看
堆栈中程序的最后一个CALL(如果它没有立刻显示出来,就只管继续寻找,比如
试试GetWindowText(),或者BPRWdiskomat(非常有用),然后一次又一次地检
查堆栈....如果这些还不成,可在内存中搜索你输入的内容,然后设置一个由对
它读写触发的断点,然后检查堆栈,堆栈,堆栈....直到找到程序(保护部分)
CALL子程序情况的列表。
∶stack;检查堆栈
USER(19)at073F:124C[?]through073F:1239
CTL3D(02)at2C3F:0D53[?]through2C3F:0D53
DISKOMAT(01)at2C97:20B9[?]through2C97:20B9
DISKOMAT(01)at2C97:3D94[?]through2C97:3D94
DISKOMAT(01)at2C97:49E2[?]through2C97:4918
DISKOMAT(04)at2C7F:EA20[?]through2C7F:EA20
USER(01)at04A7:19BE[?]throughUSER!GETWINDOWTEXT
==CTL3D(02)at2C3F:24BE[?]through04A7:3A3C
多么漂亮的堆栈大搜捕!立刻在EA20处用BPX命令。
2C7F:EA359A25ABA704CALLUSER!GETWINDOWTEXT
2C7F:EA3A8D46AELEAAX,[BP-52];载入指向"+ORC+ORC"的指针
2C7F:EA3D16PUSHSS;保存指针段址
2C7F:EA3E50PUSHAX;保存指针偏移
2C7F:EA3F9A768D872CCALL2C87:8D76;取得"ORC+ORC"长度
2C7F:EA4483C404ADDSP,+04
2C7F:EA473D2800CMPAX,0028
2C7F:EA4A762CJBEEA78
...
2C7F:EA978D46AELEAAX,[BP-52];载入指向"+ORC+ORC"的指针
2C7F:EA9A16PUSHSS;从这里开始做各种各样的计算
2C7F:EA9B50PUSHAX;我们暂且不去管它
...;....
2C7F:EAB20F851101JNEEBC7
2C7F:EAB68D8E5CFFLEACX,[BP+FF5C];指向"12121212"
2C7F:EABA16PUSHSS
2C7F:EABB51PUSHCX
2C7F:EABC9A768D872CCALL2C87:8D76;取得"12121212"长度
2C7F:EAC183C404ADDSP,+04
2C7F:EAC450PUSHAX
2C7F:EAC58D865CFFLEAAX,[BP+FF5C];指向"12121212"
2C7F:EAC916PUSHSS
2C7F:EACA50PUSHAX
...下面开始对输入作各种各样的计算
好了,够了:显然后面的代码是计算注册码的,然后悄悄地进行比较以区分那些
是合法用户、那些是可恶的解密者。你可以继续检查下去,CRACKIT...
但是神奇的一刻已经到了!我们已经知道和*感觉到*那个真正的东西一定在某个
地方....我们如何找到它?在内存中搜索"12121212"至少得到10个不同的结果....
∶s30:0lffffffff'12121212'
PatternFoundat0030:0005AD6A
....(7more)
PatternFoundat0030:80509D6A
PatternFoundat0030:8145AD6A
我们是不是要把所有出现字符串'12121212'的地方±0X90的范围内都搜寻一遍...
直到找到真正的注册码?我们可以,而且也行得通....但太烦人了!在其它程序中
这种字符串可能被有意的扩散,以防止那些碰运气的解密者。应该还有其它的方
法...哦,有了!这里有个更快的办法...代码中最后一次载入输入字符串的指针
(在计算长度后面的)就是我们要拆解的那个,因为程序保护部分就紧接在后面
(多数情况下)。(因为我们正在考察的代码有很多的堆栈操作...如果你想做更
高级的拆解,我建议你读些好的关于INETEL处理器中堆栈工作原理、堆栈的秘密
和魔术的教科书):
载入名字字符串-计算长度
载入名字字符串-对名字字符串进行转换
载入注册码字符串-计算注册码字符串长度
载入注册码字符串
*输入应该在这里*
转换注册码字符串
*结果应该在这里*
比较转换后的名字和转换后的注册码
这意味着在下面一行
2C7F:EAC58D865CFFLEAAX,[BP+FF5C];指向"12121212"
你在某个地方已经有结果了..赶紧看看[BP+FF5C]中指针的附近:
∶d2c5f:61e8;这些数字可能根据你的机器而不同
02622F060200262E-A34EA34E01003830.b/...&..N.N..80
33372D3634362D33-383336000106020037-646-3836.....
2F067562C32EB704-F2242F06CE6E2F06/.ub.....$/..n/.
49005A000100-042C2F06AE2436620000I.Z......,/..$6b
74627A2EB7043662-0100C2622F2C262Etbz...6b...b/,&.
0301BA0FAE245F02-C9015E02BA015F02.....$_...^..._.
3132313231323132-000C00BC0200000012121212........
004900BA0F-AE24F2242F060000000000....I....$.$/...
AF1700E25F-7A62FEFF791BBA0F000000......._zb..y...
960B0100024E00-37018A62D20F8F1700.....N..7..b....
2F06003701-9862201016032F06000000/.....7..b.../.
C2622B4F52432B4F-5243000DAE242F06.b+ORC+ORC......
所有的东西都在这里啦!堆栈指针指向中间部分——字符串"12121212"所在
的地方.在向上0x50字节的地方你会看到我们的老朋友,即真正的passnumber,
0x50字节以下的地方,你看到了你的名字:我这里是"+ORC+ORC"。
拆解成功了!我的"+ORC+ORC"的注册码是8037-646-3836...现在你可以开始给
自己的名字找个注册码了——如果你想重新学习一遍的话。
-Unregister,然后用自己的名字,找出注册码。不要用别人已有注册码的名
字,那样的话就是偷而不是拆解了。我将把网上那些注册码都删掉,因为我
喜欢真正桀傲不训的人,而厌恶愚蠢的小偷。
-研究两个代码的算法:一个是输入姓名的,另一个是输入数字的,这对你以
后的拆解非常有好处
-找出比较部分,即设置两个标志以区分“合法用户,你可以进入”和“可恶的
解密者,滚开”。还有:
-生成一个真正的拆解版本,可以让任何人用任何名字和注册码都可进入。
(未完待续....)
译者注:
1.Bingo是一种使用记有数目的牌所玩的彩票式赌博游戏,一个人获
胜时他会大叫一声"Bingo!",相当于我们的“中啦”、“胡啦”)
2.本文及WIN4MANT.EXE已上传至蓝天龙加密解密区,名字CRACKIT2.RAR
------------------------------------------------------------------------
在各位战友的热情鼓励下,我也顾不得自己的臭水平了:-),送上这篇+ORC的拆解入
门。为了不犯低级错误,我都将文中提到的软件找到,并实际拆一遍。但是因为我
也是个初学者,没多少经验可言,如果翻译过程当中有什么错误的话,请你一定指出
来,别让我当着这么多人的面犯傻:—-(。
第9课以前都是关于DOS方面的,所以我先从WINDOWS部分译起。+ORC的文章要比ED!SON
的难懂些,但只要实际操作一遍也能很快明白。拆解一个程序并非只有一种方法,
大家最好能把自己的方法说一说,彼此交流交流,这样就达到我们当初的目的了。
请不要拆解国产软件,即使拆了也不要散布注册码!
注:嘿嘿
预告:三、五天后我会送上第一部分的下半节:拆解SnapShotFORWIN95/NT.
大家可以先自己拆拆试试。软件可以在上述的CRACKIT2.RAR中找到,也可以到INET上
下载:
ftp://ftp.radio-msu.net/mirror/Coast/win95/graphics/snap254.zip
ftp://ftp.winsite.com/pub/pc/win3/util/wn4m110.zip
Happycracking!
--
相爱的时候,真诚比才华更重要!
--
Nobrain,nopain.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -