2017-09-06 10 views
1

QTが新しく、暗号化された関数を作成しようとしています。(例えば、私は暗号化と同じプログラムで解読)実行時に関数を解読して使用するQT C++

  • は、機能ページのrwxの
  • はそれを暗号化します
  • を関数へのポインタを取る:総合何をC/C++でやることはある
  • それを解読し、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

私は言う、私は、クライアントがサーバーから実行する必要がある機能を要求し、サーバがあれば、それに送信し、サーバクライアントスキーマを構築します(ネットワーク上で暗号化された関数を渡す場合それは承認されています)関数が崩壊しないようにシンボルを配置するにはどうすればよいですか?

QTに私はDEPとASLR防御をオフにすることができますどのようにPS3

? (私はPS 2.を実行できるように、私の意見では、私はそれらをキャンセルしなければならない)

おかげ ヨーコ

答えて

2

は例が私のシステムで未定義の動作です。あなたは、コンパイラはパディングなしTestFunctionFunctionStubを置くことを前提としてい

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

あなたのコードの最初と主な問題があります。私はあなたの例をコンパイルし、私のケースではFunctionStubTestFunctionを超え、負のdwFunctionSizeになっていました。

dwFunctionSize = (fnB - fnA); 

TestFunction located at @ 0xa11d90 
FunctionStub located at @ 0xa11b50 
dwFunctionSize = -0x240 

またXorBlockに

addr[i] ^= 0xff; 

は何もしません。

あなたは、XORにメモリロケーションにXORBlockを書き込み、TestFunction全体を書き込むと仮定します。私はあなたの例のいずれかのQtの固有のを見ることはできません

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

あなたはこのような何かを行うことができます。 Qt関数呼び出しであっても、単なる呼び出しです。だから私は両方の例では未定義の動作があると思いますが、2番目の例だけがクラッシュします。

コンパイラとリンカが関数の順序を保持する理由がわかりません。たとえば、GCCでは各関数のコードセクションを指定できます。したがって、cppで並べ替えをせずに実行可能ファイルに並べ替えることができます。

私はそれが動作するようにいくつかのコンパイラ固有のものが必要だと思います。

関連する問題