Obstrucción binaria de C ++: ¿cómo sortear los controles de licencia siendo un simple si / entonces sucursales?

2

Estoy buscando ofuscación binaria para un binario ejecutable escrito en C ++. Me doy cuenta de que es imposible prevenir las grietas, pero hacerlo bien sería bueno.

No importa qué tan complejo sea el esquema de licencia real, no puedo pensar en una manera de validarlo que no se reduzca a:

if (doVeryComplexLicenseValidationCheck())
{
    //execute code
}

... que sería trivialmente fácil de evitar por cualquier cracker competente. Pero obviamente hay muchos sistemas de protección contra copia que han sido muy difíciles de descifrar ... así que, ¿qué están haciendo y me estoy perdiendo? ¿Hay alguna manera de ofuscar una rama simple como esa, que es mucho más difícil de omitir?

    
pregunta Tyson 24.09.2018 - 20:11
fuente

1 respuesta

-1

Aquí hay algunos consejos que pueden ayudarlo, pero recuerde que cualquiera que tenga un buen conocimiento del ensamblador lo encontrará.

Imaginemos que su programa es como lo describe:

int main() {

    if (myCheck()) {
            std::cout << "License pass\n";
    }
    ....

Y aquí está el desensamblador del código.

00000000004006d3 <main>:
4006d3:       55                      push   %rbp
4006d4:       48 89 e5                mov    %rsp,%rbp
4006d7:       e8 da ff ff ff          callq  4006b6 <_Z7myCheckv>
4006dc:       84 c0                   test   %al,%al
4006de:       74 0f                   je     4006ef <main+0x1c>
4006e0:       be d1 07 40 00          mov    $0x4007d1,%esi
4006e5:       bf 40 10 60 00          mov    $0x601040,%edi
4006ea:       e8 b1 fe ff ff          callq  4005a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
4006ef:       b8 00 00 00 00          mov    $0x0,%eax
4006f4:       5d                      pop    %rbp
4006f5:       c3                      retq

Entonces al agregar declaraciones asm en tu código, puedes hacerlo más difícil.

#define OPS1 "xor \%rbx,\%rbx\n"
int main() {
    __asm__ volatile (
            "push %rax\n"
            "xor %rax,%rax\n"
            "pop %rax\n"
    );

    if (myCheck()) {
            std::cout << "License pass\n";
    }
    __asm__ volatile (OPS1);

Y aquí está la salida

4006d3:       55                      push   %rbp
4006d4:       48 89 e5                mov    %rsp,%rbp
4006d7:       50                      push   %rax
4006d8:       48 31 c0                xor    %rax,%rax
4006db:       58                      pop    %rax
4006dc:       e8 d5 ff ff ff          callq  4006b6 <_Z7myCheckv>
4006e1:       84 c0                   test   %al,%al
4006e3:       74 0f                   je     4006f4 <main+0x21>
4006e5:       be e1 07 40 00          mov    $0x4007e1,%esi
4006ea:       bf 40 10 60 00          mov    $0x601040,%edi
4006ef:       e8 ac fe ff ff          callq  4005a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
4006f4:       48 31 db                xor    %rbx,%rbx
4006f7:       b8 00 00 00 00          mov    $0x0,%eax
4006fc:       5d                      pop    %rbp
4006fd:       c3                      retq

Este caso es realmente sencillo, pero si tienes un buen conocimiento de las plantillas, el ensamblador complica un poco el código generado.

    
respondido por el camp0 24.09.2018 - 21:54
fuente

Lea otras preguntas en las etiquetas