【问题标题】:decrypt function at run time and use it QT c++在运行时解密函数并使用它 QT c++
【发布时间】:2017-09-06 12:54:04
【问题描述】:

我是 QT 新手,我正在尝试创建一个加密函数。 总体而言,您在 C/C++ 中所做的是:

  • 将指针指向函数
  • 将功能页设为rwx
  • 加密(以我在同一个程序中加密和解密为例)
  • 解密并运行它

一个简单的 C 代码大致如下:

    void TestFunction()
{
    printf("\nmsgbox test encrypted func\n");
}
// use this as a end label
void FunctionStub() { return; }

void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
    char * addr = (char *)dwStartAddress;
    for (int i = 0; i< dwSize; i++)
    {
        addr[i] ^= 0xff;
    }
}

DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
    DWORD dwFunctionSize = 0, dwOldProtect;
    DWORD *fnA = NULL, *fnB = NULL;

    fnA = (DWORD *)Function;
    fnB = (DWORD *)StubFunction;
    dwFunctionSize = (fnB - fnA);
    VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // make function page read write execute permission
    return dwFunctionSize;
}



int main()
{

    DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
    printf("use func");
    TestFunction();
    XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function
    printf("after enc");
    //TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.

    XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function
    printf("after\n");
    TestFunction(); // Fine here

    getchar();
}

当我尝试在 QT 中运行这样的示例时,出现运行时错误。

这是QT中的代码:

    void TestFunction()
{
    QMessageBox::information(0, "Test", "msgbox test encrypted func");
}
void FunctionStub() { return; }

void XorBlock(DWORD dwStartAddress, DWORD dwSize)
{
    char * addr = (char *)dwStartAddress;
    for (int i = 0; i< dwSize; i++)
    {
        addr[i] ^= 0xff;                // here i get seg. fault
    }
}

DWORD GetFuncSize(DWORD* Function, DWORD* StubFunction)
{
    DWORD dwFunctionSize = 0, dwOldProtect;
    DWORD *fnA = NULL, *fnB = NULL;

    fnA = (DWORD *)Function;
    fnB = (DWORD *)StubFunction;
    dwFunctionSize = (fnB - fnA);
    VirtualProtect(fnA, dwFunctionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect); // Need to modify our privileges to the memory

    QMessageBox::information(0, "Test", "change func to read write execute ");
    return dwFunctionSize;
}




void check_enc_function()
{

    DWORD dwFuncSize = GetFuncSize((DWORD*)&TestFunction, (DWORD*)&FunctionStub);
    QMessageBox::information(0, "Test", "use func");
    TestFunction();
    XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR encrypt the function -> @@@ i get seg fault in here @@@
    QMessageBox::information(0, "Test", "after enc");


    TestFunction(); // If you try to run the encrypted function you will get Access Violation Exception.

    XorBlock((DWORD)&TestFunction, dwFuncSize); // XOR decrypt the function
    QMessageBox::information(0, "Test", "after dec");
    TestFunction(); // Fine here

    getchar();
}

为什么会发生这种情况? QT 的行为应该像标准 C++ 一样精确......

发布 Scriptum。

有趣的是,在同一件事上,保持重要功能加密的最合法方法是什么(加密的原因是 DRM)?

我的意思是,防病毒软件不会因为我保护自己而错误地将我标记为病毒。

PS2

如果我通过网络传递一个加密函数(例如,我将构建一个服务器客户端模式,客户端要求它从服务器运行它需要的函数,如果它被批准,服务器将它发送给它)如何我排列符号,使功能不崩溃?

PS3

如何在 QT 中关闭 DEP 和 ASLR 防御? (我认为这样我才能执行 PS 2。我必须取消它们)

谢谢 洋子

【问题讨论】:

    标签: qt antivirus drm


    【解决方案1】:

    这个例子是我系统上未定义的行为。

    您的代码中的第一个也是主要问题是:

    void TestFunction() { /* ... */ }
    void FunctionStub() { return; }
    

    您假设编译器会将FunctionStub 放在TestFunction 之后而没有任何填充。我编译了您的示例,在我的情况下,FunctionStub 高于TestFunction,导致 dwFunctionSize 为负数。

    dwFunctionSize = (fnB - fnA);
    
    TestFunction located at @ 0xa11d90
    FunctionStub located at @ 0xa11b50
    dwFunctionSize = -0x240
    

    也在 XorBlock 中

    addr[i] ^= 0xff;
    

    什么都不做。

    我假设您想在 XorBlock 中写入内存位置以异或整个 TestFunction

    你可以这样做:

    void XorBlock(DWORD dwStartAddress, DWORD dwSize)
    {
        DWORD dwEndAddress = dwStartAddress + dwSize;
        for(DWORD i = dwStartAddress; i < dwEndAddress; i++) {
            // ...
        }
    }
    

    【讨论】:

      【解决方案2】:

      我在您的示例中看不到任何特定于 Qt 的内容。即使它是 Qt 函数调用,它也只是一个调用。所以我猜你在两个例子中都有未定义的行为,但只有第二个崩溃了。

      我看不出编译器和链接器有任何理由保持函数顺序。例如,GCC 允许您为每个函数指定代码段。因此,您可以在可执行文件中对其重新排序,而无需在 cpp 中重新排序。

      我认为您需要一些特定于编译器的东西才能使其工作。

      【讨论】:

        猜你喜欢
        • 2018-11-25
        • 2014-01-08
        • 2011-02-04
        • 1970-01-01
        • 2013-12-21
        • 2014-09-12
        • 1970-01-01
        • 1970-01-01
        • 2017-03-30
        相关资源
        最近更新 更多