玖公子 发表于 2019-8-28 19:05

新手初学c语言,做的一个小游戏!

本帖最后由 玖公子 于 2019-8-28 19:14 编辑




到现在也学了半个月的C语言,这是我自己做的一个小游戏,用的VC++6.0编译器编写!
这是游戏失败截图!
实在不会字符串加密,程序只能裸奔,纯编译器编写,未添加任何东西!


在此,希望各位前辈能给出分析思路,不要就只有一个截图,楼主破解连门
都没入,就一张图我看不懂!(让我们一起遵守新的版规吧!)
CM区新加版规如下

1.作为一个Cracker在破解别人的CM后,请贴上你的破解和分析思路(只是贴上一个成品图或者成品意义不大)

2.在发布CM被人破解或无人破解一段时间后应该要公开自己CM的代码,或自己贴出破解方式以及过程。

3.发布CM须标明是否加壳,编写语言,有无混淆,花指令等等,如有特殊不便告知,须说明。


PS:项目源码和程序一起上传,破解成功后,在命令行会输出压缩包解压密码!







梦游枪手 发表于 2019-8-28 19:49

用IDA分析的结果差不多如下
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v1; // eax
int v4; // eax
char v6; //
int v7; //
int v8; //
int v9; //
int v10; //
char v11; //
int v12; //
int *v13; //
int v14; //
int *v15; //
int v16; //
__int16 v17; //
int v18; //
char v19; //
int v20; //
human boss; //
human me; //

strcpy((char *)&v18, "真密码:");
strcpy((char *)&v16, "52pojie");
boss.name = 's';
boss.name = 's';
v1 = 0xA;
v19 = 0;
v17 = 0;
strcpy(&v20, "123456789");
boss.name = 'b';
boss.name = 'o';
boss.name = 0;
boss.attack = 3;
boss.hp = 0xA;
me.name = 'm';
me.name = 'e';
me.name = 0;
me.attack = 1;
me.hp = 0xA;
do
{
    if ( me.hp <= 0 )
      break;
    qmemcpy(&v11, &me, 0x14u);
    qmemcpy(&v6, &boss, 0x14u);
    v4 = printresult(v6, v7, v8, v9, v10, v11, v12, (int)v13, v14, (int)v15);
    if ( attack(&boss, &me, v4) <= 0 )
      printf(invaild);
    v1 = boss.hp;
}
while ( boss.hp > 0 );
if ( v1 < 0 || v1 > 0 )
    MessageBoxA(0u, failed, failed, 0x30u);
if ( me.attack != 1 || boss.attack != 3 )
    MessageBoxA(0u, failed, failed, 0x30u);
if ( me.hp <= 0 )
{
    MessageBoxA(0u, failed, failed, 0x30u);
}
else
{
    v15 = &v18;
    printf(aS_0, &v18);
    LOWORD(v16) = v20;
    v13 = &v16;
    BYTE2(v16) = BYTE2(v20);
    printf(aS, &v16);
    system(aPause);
}
return 0;
}
虽然有部分错误,但是能看懂就行。
我猜测的human struct定义如下

虽然有判断了me和boss的攻击力,但是没有判断初始化的血量,所以把boss血量改1就能秒了。


一刀劈死无鸭梨。

飞翔病毒 发表于 2019-8-28 21:23

我最多"HELLO WORLD"
下边就进行不下去了
感觉可能是数学和英文差的离谱的原因

玖公子 发表于 2019-8-29 10:22

云梦墨溪 发表于 2019-8-28 22:44
楼主好厉害啊,半个月就有这么好的思路,我以为是打印菜单,然后输入判断技能然后看不 ...

就是你想的这样啊,然后嘿嘿,后面代码都是假的,啥也没干,所以想打赢boss就必须修改游戏数据了!

jidesheng6 发表于 2019-8-28 20:19

本帖最后由 jidesheng6 于 2019-8-28 20:22 编辑


这个是成功的图片

一开始下了一个MessageBoxA断点,断下来了,然后去查看调用的call,在查看跳转的时候网上看会看到什么真密码,下面有个52pojie
这个初步怀疑的用来迷惑的


暂时从MessageBox跳转下手,失败会弹出两次信息框,应该是进行两次对比验证吧,防止别人跳过你的信息框,于是就单步跟,发现you failed这个信息框确实是调用两次,两个跳转改一下
不跳的跳过去,跳的NOP掉

之后单步

堆栈窗口就会出现如下信息,然后运行到输出密码的那个call返回控制台就可以看到了

玖公子 发表于 2019-8-28 21:44

梦游枪手 发表于 2019-8-28 19:49
用IDA分析的结果差不多如下
int __cdecl main(int argc, const char **argv, const c ...

腻害了,谢谢你的指导交流!

玖公子 发表于 2019-8-28 22:01

jidesheng6 发表于 2019-8-28 20:19
这个是成功的图片

一开始下了一个MessageBoxA断点,断下来了,然后去查看调用的call,在查看跳转的时 ...

因为我想到之前发的字符串都是一下子被右键中文搜索看出来,直接nop破解了。
所以我就开始初始化了一个假字符串,然后在通过c语言自带的拷贝字符串函数,覆盖掉前面几个字符。

云梦墨溪 发表于 2019-8-28 22:44

{:301_993:}楼主好厉害啊,半个月就有这么好的思路,我以为是打印菜单,然后输入判断技能{:301_1001:}然后看不懂程序了,哈哈哈

冥界3大法王 发表于 2019-8-29 08:37

这个会了也不错,可以用c写注册机了,内嵌汇编代码确实是方便啊。

妙哉春风 发表于 2019-8-29 09:20

我当时做的第一个小游戏是扫雷

流浪星空 发表于 2019-8-29 09:23

飞龙在天,震雷削;www
页: [1] 2 3 4 5
查看完整版本: 新手初学c语言,做的一个小游戏!