吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 783|回复: 12
收起左侧

[求助] 求助C++编程大佬

[复制链接]
朱朱你堕落了 发表于 2024-4-3 11:34
300吾爱币
本帖最后由 朱朱你堕落了 于 2024-4-3 11:41 编辑

某一软件,很老版本的时候研究过,心跳包验证在线程里,找到这个线程函数,ret掉即可。
但是后来发现新版本用这种方法不行了,验证还是在线程函数里,这一点是没变的,但是若还像
以前一样ret掉,程序就崩溃了,应该是作者做了防ret处理,类似于易语言的防push窗体吧。

所以想到编程中是如何实现的,写个类似代码吧:

#include "stdafx.h"
#include <Windows.h>

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
        MessageBoxA(NULL, _T("from ThreadProc"), _T("Test"), 0);
        return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
        printf("from _tmain...\n");
        printf("ThreadProc addr = 0x%08X\n", (DWORD)ThreadProc);
        CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
        system("pause");
        return 0;
}

ThreadProc的地址为00401000(这里我设置了固定基址),现在retn 0x4,保存成功,
运行后程序不弹窗了,程序也正常运行。

OK,请大佬们发挥比较好的创意想法,添加一些代码,如果还是把00401000这个地址ret 0x4,程序崩溃无法
正常运行,就是说,这个线程必须存在,而且不能被ret 0x4掉程序才正常运行,如果ret 0x4掉那么程序崩溃。
如何实现这个功能?

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

无闻无问 发表于 2024-4-3 12:13
我觉得方法很多吧,比如另一个线程对它进行CRC,或线程中加个信号量,其它地方验证……

点评

对代码做CRC验证这个并不好,不是麻烦吗?应该有更简单的方法或巧妙的方法吧。  详情 回复 发表于 2024-4-3 12:51
 楼主| 朱朱你堕落了 发表于 2024-4-3 12:51
无闻无问 发表于 2024-4-3 12:13
我觉得方法很多吧,比如另一个线程对它进行CRC,或线程中加个信号量,其它地方验证……

对代码做CRC验证这个并不好,不是麻烦吗?应该有更简单的方法或巧妙的方法吧。
JuncoJet 发表于 2024-4-3 13:34
检测内存补丁,还是检测物理修改两个实现不一样
nymo 发表于 2024-4-3 13:35
CRC不算麻烦,也比较常用,类似这样:

unsigned int easyCRC(void* func, size_t size) {
    unsigned checksum = 0;
    unsigned char* bytes = (unsigned char*)func;
    for(size_t i = 0; i < size; i++) {
        checksum += bytes[i];
    }
    return checksum;
}

这里只是简单加了一下,也可以更复杂。size和CRC值需要先跑出来再填回去。
yes2 发表于 2024-4-3 13:37
crc并无不好。
另外的思路简单点就是线程里搞个变量做个递增,直接ret变量肯定就不会变化了。
董督秀 发表于 2024-4-3 13:47
考虑用异常处理,在线程函数的段首设置硬断,触发异常后执行eip跳转到retn。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
朱朱你堕落了 + 1 + 1 我的意思是,我如何重现作者这个方法,自己实现下。

查看全部评分

无闻无问 发表于 2024-4-3 13:48
yes2 发表于 2024-4-3 13:37
crc并无不好。
另外的思路简单点就是线程里搞个变量做个递增,直接ret变量肯定就不会变化了。

就是类似信号量的东东
无闻无问 发表于 2024-4-3 13:51
朱朱你堕落了 发表于 2024-4-3 12:51
对代码做CRC验证这个并不好,不是麻烦吗?应该有更简单的方法或巧妙的方法吧。

那可检测函数头或遍历整个函数块,发现有2个ret指令,就抛空指针……
 楼主| 朱朱你堕落了 发表于 2024-4-3 14:32
做CRC校验,我说不好的意思是:做CRC前提是无壳的,无壳的就容易被分析出来,与其做CRC这么费劲,那还如何把线程这段代码VM起来更省事。

int g_int = -1;
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
        g_int = 1;
        MessageBoxA(NULL, _T("from ThreadProc"), _T("Test"), 0);
        return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
        printf("from _tmain...\n");
        printf("ThreadProc addr = 0x%08X\n", (DWORD)ThreadProc);
        HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
        if (g_int == -1)
        {
                printf("线程已经被ret掉了");
                __asm int 3;
        }
        system("pause");
        return 0;
}
我这样写个demo,哈哈,我main函数和ThreadProc函数都VM起来,你牛B你就去还原吧,但是这里有个问题,使用了WaitForSingleObject函数,这就意味着main函数要等待线程函数走完,接下来才能继续运行main函数,
这不是我想要的,所以这里我只是抛砖引玉,我想让线程和main函数“独立”出来,或是说不要让谁来等谁执行完。反正大概就是这个意思吧,大佬们比我这菜鸟水平高,你们懂我的意思,请帮忙写下代码。

@无闻无问 @JuncoJet @nymo @yes2 @董督秀



您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-2 23:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表