2017-09-06 49 views
1

我是QT新手,我試圖創建一個加密函數。 總體在C/C++做的是什麼:在運行時解密函數並使用它QT 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++那樣精確表現...

post Scriptum。

有趣的是,在同樣的事情中,保持重要功能加密的最合法的方式是什麼(它被加密的原因是DRM)?

正確地說,我的意思是反病毒不會因爲我自己辯護而將我標記爲病毒。

PS2

如果我通過一個加密的功能,通過網絡(比如,我將構建一個客戶要求它需要從服務器上運行的功能,如果服務器發送給它的服務器端架構它被批准)我如何安排這些符號以便函數不會崩潰?

PS3

如何在QT我可以關閉DEP和ASLR防禦? (在我看來,這樣我可以執行PS 2.我不得不取消他們)

感謝 洋子

回答

2

的例子是我的系統上未定義行爲。

第一,主要問題在你的代碼是:

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

您認爲編譯器會把FunctionStubTestFunction後沒有任何填充。我編譯你的例子,在我的情況下,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++) { 
     // ... 
    } 
} 
1

我無法看到Qt的具體您的示例中的任何。即使它是Qt函數調用,它只是一個調用。所以我想你在這兩個例子中都有未定義的行爲,但只有第二個崩潰。

我看不到任何編譯器和鏈接器保持函數順序的原因。例如GCC讓你指定每個函數的代碼部分。所以你可以在可執行文件中重新排序而不用在cpp中重新排序。

我想你需要一些編譯器特定的東西來使它工作。

相關問題