首页
社区
课程
招聘
[原创]freefilesync文件校验和性能限制分析
发表于: 2025-5-7 19:58 4104

[原创]freefilesync文件校验和性能限制分析

2025-5-7 19:58
4104

该分析只用于技术研究,切勿非法用途

阅读开源代码找到关键函数

在函数体发现

动态调试找到该位置

nop掉call后,发现控件已经变成可用

保存补丁后,运行后结果有校验,点确认后程序退出

根据信息调试,找到验证关键地方,WV错误信息暴力了验证位置

验证完整行关键代码

freefilesync在官方版本里存在开源代码里没有的代码,这些代码使用了一个简单的字符串混淆函数

IDA 伪代码

AI+优化后代码,全部代码

运行结果

运行结果

使用WinVerifyTrust函数判断证书是否有效从而判断文件是否被修改,只要让函数返回正确值,或者修改后续跳转,程序能正确运行,并调整并行性能可以正确使用

CloudSetupDlg::CloudSetupDlg(wxWindow* parent, Zstring& folderPathPhrase, Zstring& sftpKeyFileLastSelected, size_t& parallelOps, bool canChangeParallelOp) :
    CloudSetupDlgGenerated(parent),
    sftpKeyFileLastSelected_(sftpKeyFileLastSelected),
    folderPathPhraseOut_(folderPathPhrase),
    parallelOpsOut_(parallelOps)
CloudSetupDlg::CloudSetupDlg(wxWindow* parent, Zstring& folderPathPhrase, Zstring& sftpKeyFileLastSelected, size_t& parallelOps, bool canChangeParallelOp) :
    CloudSetupDlgGenerated(parent),
    sftpKeyFileLastSelected_(sftpKeyFileLastSelected),
    folderPathPhraseOut_(folderPathPhrase),
    parallelOpsOut_(parallelOps)
m_spinCtrlConnectionCount->SetValue(parallelOps);
 
m_spinCtrlConnectionCount->Disable(); //这里禁用了控件
m_staticTextConnectionCountDescr->Hide();
 
m_spinCtrlChannelCountSftp->Disable();
m_buttonChannelCountSftp  ->Disable();
m_spinCtrlConnectionCount->SetValue(parallelOps);
 
m_spinCtrlConnectionCount->Disable(); //这里禁用了控件
m_staticTextConnectionCountDescr->Hide();
 
m_spinCtrlChannelCountSftp->Disable();
m_buttonChannelCountSftp  ->Disable();
char *__fastcall decodestring(char *outstr, char *inputstr, int key)
{
char *v3; // r9
int v5; // r8d
int v6; // ebx
char *v7; // rcx
char *v8; // r8
char *v9; // r10
char *result; // rax
 
v3 = inputstr;
v5 = key % 95;
v6 = v5 + 95;
if ( v5 >= 0 )
v6 = v5;
if ( *((_QWORD *)inputstr + 3) <= 0xFui64 )
{
v7 = inputstr;
v8 = inputstr;
}
else
{
v7 = *(char **)inputstr;
inputstr = *(char **)inputstr;
v8 = (char **)v3;
}
v9 = &inputstr[((_QWORD *)v3 + 2)];
if ( v8 != v9 )
{
do
{
if ( (unsigned __int8)(*v7 - 32) <= 0x5Eu )
*v7 = (*v7 + v6 - 32) % 95 + 32;
++v7;
}
while ( v7 != v9 );
}
*(_OWORD *)outstr = 0i64;
*((_QWORD *)outstr + 2) = 0i64;
*((_QWORD *)outstr + 3) = 0i64;
*(_OWORD *)outstr = *(_OWORD *)v3;
*((_OWORD *)outstr + 1) = *((_OWORD *)v3 + 1);
*((_QWORD *)v3 + 3) = 15i64;
*((_QWORD *)v3 + 2) = 0i64;
*v3 = 0;
result = outstr;
*((_QWORD *)v3 + 3) = 15i64;
return result;
}
char *__fastcall decodestring(char *outstr, char *inputstr, int key)
{
char *v3; // r9
int v5; // r8d
int v6; // ebx
char *v7; // rcx
char *v8; // r8
char *v9; // r10
char *result; // rax
 
v3 = inputstr;
v5 = key % 95;
v6 = v5 + 95;
if ( v5 >= 0 )
v6 = v5;
if ( *((_QWORD *)inputstr + 3) <= 0xFui64 )
{
v7 = inputstr;
v8 = inputstr;
}
else
{
v7 = *(char **)inputstr;
inputstr = *(char **)inputstr;
v8 = (char **)v3;
}
v9 = &inputstr[((_QWORD *)v3 + 2)];
if ( v8 != v9 )
{
do
{
if ( (unsigned __int8)(*v7 - 32) <= 0x5Eu )
*v7 = (*v7 + v6 - 32) % 95 + 32;
++v7;
}
while ( v7 != v9 );
}
*(_OWORD *)outstr = 0i64;
*((_QWORD *)outstr + 2) = 0i64;
*((_QWORD *)outstr + 3) = 0i64;
*(_OWORD *)outstr = *(_OWORD *)v3;
*((_OWORD *)outstr + 1) = *((_OWORD *)v3 + 1);
*((_QWORD *)v3 + 3) = 15i64;
*((_QWORD *)v3 + 2) = 0i64;
*v3 = 0;
result = outstr;
*((_QWORD *)v3 + 3) = 15i64;
return result;
}
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
 
typedef struct {
    union {
        char* ptr;
        char    local_buf[16];
    };
    size_t  size;
    size_t  capacity;
} EncryptedString;
 
int64_t decodestring(int64_t dest_ptr, EncryptedString* src, int key)
{
    int shift = key % 95;
    if (shift < 0)
    {
        shift += 95;
    }
 
    char* data_start;
    if (src->capacity <= 15)
    {
        data_start = src->local_buf;
    }
    else {
        data_start = src->ptr;
    }
 
    size_t  length = src->size;
    char* data_end = data_start + length;
 
 
    for (char* p = data_start; p < data_end; ++p)
    {
        unsigned char c = *p;
        if (c >= 32 && c <= 126)
        {
            c = (c - 32 + shift) % 95;
            *p = (char)(c + 32);
        }
    }
    EncryptedString* dest = (EncryptedString*)dest_ptr;
    *dest = *src;
    src->capacity = 15;
    src->size = 0;
    src->local_buf[0] = '\0';
 
    return(dest_ptr);
}
 
 
int main(void)
{
    char    out1[256] = { 0 };
    char    out2[256] = { 0 };
 
    char    p1[] = {
        0x5E, 0x70, 0x75, 0x5D, 0x6C, 0x79, 0x70, 0x6D, 0x21, 0x5B, 0x79, 0x7C, 0x7A, 0x7B, 0x00, 0x00,
        0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    char    p2[] = {
        0x5F, 0x71, 0x76, 0x7C, 0x7A, 0x7D, 0x7B, 0x7C, 0x36, 0x6C, 0x74, 0x74, 0x00, 0x00, 0x00, 0x00,
        0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
 
    decodestring(out1, p1, 0xFFFFFFF9);
    decodestring(out2, p2, 0xFFFFFFF8);
 
    printf("%s\n", out1);
    printf("%s\n", out2);
    return(0);
}
#include <Windows.h>

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-5-7 20:12 被九耀计都编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (1)
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
为你点赞!
2025-6-19 22:29
0
游客
登录 | 注册 方可回帖
返回