已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
老外给这个CRACKME写的破文

1. Main()

Firing up the executable in OllyDbg (OEP - 0x00401000) raises a couple of eyebrows. A PUSHAD/CALL to a function that increases the stack pointer and rets into a JMP over a bunch of NOPs. It looks like the author had a lot of fun writing this program.

The next thing we see is a dialog box being created through the user32.DialogBoxParamA function with the template name set as "IsDebugPresent" (hmmmm).

The window event processing loop follows.

1.5. Entering in your Name/Key

Enter in any values you want here. Press the RegMe button and place a breakpoint on one of the two addresses listed in the next section.

2. EventProcessing()

None of the information in this function actually matters except for the part where the values from the YourName/YourID are copied into memory.

On lines 0x0040112F and 0x00401145 we see two sequential XXXXXXXXXtDlgItemTextA's. These corresponding to the copying of the name and key into memory.

Following our previous copies is an all too familiar call to XXXXXXXXXXXrtualProtect making the .text section writable. And so begins the morphing code.

3. Anti-Debugging and Morphing Code

The next sections of code, beginning at 0x004011C5 were created to transform sections of the code which appear to be data into actual executable code. I will not discuss every section in detail as most are just simple XORs or additions of hardcoded constants. Instead, I will try to explain the general program flow on a higher level.

0x004011E3 and 0x00401205 are both LOOPD-based loop statements that transform some of the .text section into more meaningful statements.

Past these two loops we will see two calls to XXXXXXXXXXXtLocalTime (0x0040120C & 0x00401230).

At 0x0040124C the milliseconds of the local times are compared. If they are not equal, which implies that we must have been single-step debugging through the section, then the program halts.

Since there is absolutely no reason to single step this section (as it simply and trivially converts more sections of code) then place a breakpoint at 0x0040124C where the compare occurs.

The compare will succeed. A new call will be generated on the spot in the following loop, the program will return to EventProcessing() and then do a modified return into code at 0x00401358.

Put a breakpoint on Call ECX at 0x00401386.

ECX is a call to a far call containing user32.BlockInput which does a "int 2e" to disrupt debugging.

To circumvent this check, trace into Call ECX, trace into the far call, and NOP out the call at line 0x77D9C648 (Windows XP SP2) inside user32. This will force nothing to happen and the code to return from the call like everything went fine.

Returning from our BlockInput call, we will find data translating. Place a breakpoint at 0x00401429 to skip past all this nonsense.

4. Last Tricks

We are now in the final code section.

Ignore the weird compares and the always weird code translations.

We see another Call ECX at the bottom. This was a dangerous part of the code last time, and its a dangerous part of the code this time. Place a breakpoint at this address (0x004014CA) and see what it finally translates to.

OutputDebugStringA(%s%s) the classic OllyDbg 1.10 crash bug. Just NOP out this entire call and continue on your merry way.


5. Name/Key initial checks

After a modified inline strlen() equivalent function, the name and key are both checked for length.

The name length check is at 0x004014F0
The key length check is at 0x00401543

If the name is greater than or equal to 10, it passes.
If the key is greater than or equal to 11, it passes.

Failure of either check causes another call to OutputDebugStringA(%s%s).

6. Final Verification

The final verification appears at 0x00401572. In a high level view you take a 4 DWORDS at different location from the username and add them together into a single DWORD. The same process is performed with the key but from different locations.

The resulting DWORD values, or hashes, are then summed with 2 different constants (which are actually locations in the code). If the 2 hashes match, then you entered a valid combination and a message box is pop'd up.


0x004015DB is the final compare.


Here is the equation that needs to be solved to generate keys for names.


n_1 + (2^8*n_2) + (2^16*n_3) + (2^24*n_4) +
n_2 + (2^8*n_3) + (2^16*n_4) + (2^24*n_5) +
n_6 + (2^8*n_7) + (2^16*n_8) + (2^24*n_9) +
n_3 + (2^8*n_4) + (2^16*n_5) + (2^24*n_6) + c_n

=

k_1 + (2^8*k_2) + (2^16*k_3) + (2^24*k_4) +
k_5 + (2^8*k_6) + (2^16*k_7) + (2^24*k_8) +
k_6 + (2^8*k_7) + (2^16*k_8) + (2^24*k_9) +
k_4 + (2^8*k_5) + (2^16*k_6) + (2^24*k_7) + c_k


Where
    - n_i is the ith character in the name
    - c_n is the name's constant
    - k_i is the ith character in the key
    - c_k is the key's constant

All of the n_i's are given by the user entered in his name. Which leaves the k_i's to be solved for. Since there are 9 variables and 1 equation, there is no simple solution for this problem.

Instead one should set the values of all of the key's characters (k_i) to set numbers and solve for the last k_i. Unfortunately, since characters can only express 2^8 different values, we can't simply set all characters to 0, and k_1 to the difference between the name hash and the key hash.

Also note that general equations have many solutions. So the user 'RedStripeBeer' will have many multiples of valid keys associated with it.


7. Algorithm Realizations

By looking at the key equation above, you will first notice that although the key needs to be 11 characters in length, k_0 and k_10 are not used for the calculation. Set these values to whatever you want.

The next thing you should notice is that each character affects a different portion of the hash based upon the position they are pointed inside the DWORD.

For instance, k_1 (since it only appears once and in the lowest byte) can only affect the hash by +255 bits. k_9, on the exact opposite of the spectrum, is being multiplied by 2^24 since it appears only once in the highest byte. This means that k_9 can affect the overall hash by (2^24 * 255).

Also you should see that some characters, such as k_7 appear affect the total hash by (2^24+2^16+2^8 * 255) which is very powerful.

8. My Solution


    a. Start with the key X000000000X.
    b. Compute the hash of the key and the name.
    c. Calculate the difference (name_hash - key_hash).
         i. If the difference is negative, we need to make it positive. The way to do this is key adding large values until the DWORD overflows into positive.
    d. When the difference becomes positive, divide the difference by the strength of the character.
    e. Increase the character by this multiple.
    f. Repeat (a) with the new key.

9. Notes/Curiosities/Anger

This program was coded for an Asian language set. This presented many challenges in finding valid characters to use for generating the key. One method I used was to alternate between powerful characters to spread the changes across the key. This prevented single characters from reaching the 254 value and ruining the algorithm.

Also, the MessageBox that pops up in the end appears to look like garbage. Are these poorly translated Asian characters? I have no way of telling.

10. See the README.txt for the solution keygen.

Have fun,

TCM
文号 / 34314

千古风流
名片发私信
学术分 3
总主题 48 帖总回复 432 楼拥有证书:学者 笔友
注册于 2008-07-22 16:19最后登录 2018-01-10 01:23
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步

个人简介

暂未填写
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
等待中...
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
处理中..
处理失败
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传,正在处理中
空空如也~
处理中...
处理失败
加载中...
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
插入公式
评论控制
加载中...
文号:{{pid}}
加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
ID: {{user.uid}}