需要帮助解释一个模糊的C++;密码?

需要帮助解释一个模糊的C++;密码?,c,obfuscation,C,Obfuscation,这段代码让我抓狂,有人能帮我解释一下吗 #include <stdio.h> char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX"; int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main (*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);} #包括 char*=“xxtihrcxc


这段代码让我抓狂,有人能帮我解释一下吗

#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
    (*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
#包括
char*=“xxtihrcxcxtihrcxtihrcxtihrcxtihrcxtihrcxtihrcx”;
intmain(intl){for(l+=7;l!=putchar(010);++l);if(*(+++)main
(*.=88?(putchar(*^ 073)| putchar(33))&1:0xffff2a8b);)
谢谢,

Chan Nguyen

为了理解此代码的工作原理,请开始以可读的方式重写它:

#include <stdio.h>

char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";

int main(int l)
{
    for( l += 7; l != putchar(010); ++l ) {
    }

    if( *(++_) ) {
        main( ( *_ != 88 ) ? ( putchar(*_^073) | putchar(33) )&1 : 0xffff2a8b );
    }

    return 0;
}
#包括
char*=“xxtihrcxcxtihrcxtihrcxtihrcxtihrcxtihrcxtihrcx”;
内部主(内部l)
{
对于(l++=7;l!=putchar(010);++l){
}
如果(*(+++){
main((*!!=88)?(putchar(*^ 073)| putchar(33))&1:0xffff2a8b);
}
返回0;
}
现在让我们了解一下:

  • 它的参数
    l
    (如果不带参数运行此程序,则为1)增加7(变为8)

  • 循环将打印
    010
    (八进制表示8:ascii退格),直到
    l==8
    (因此,运行程序时它不会执行任何操作)

  • 如果
    \uu
    指向的下一个字符(现在是
    x
    )不同于0(这可能意味着“直到我们到达
    \u
    的末尾”),则调用
    main
    ,但让我们看看在评估其参数时会发生什么:

    • 当前由
      \uu
      指向的字符与88不同(88在ascii中是
      x
      ),因此main的参数将是表达式
      (putchar(*u073)| putchar(33))&1的结果:

      计算
      main
      的参数时,将打印两个字符

      • 第一个是:
        *.^073
        ,就是这样,
        120^59
        (因为
        x
        是120,在ascii中是120,八进制中的073是59,在十进制中是59),这就是
        67
        :120(
        0b1000011
        )XOR 59(
        0b111011
        )=67
        0b1000011

      • 第二个是33(

      main
      参数随后将是
      (67 | 33)&1
      的结果,即1

如果你真的想了解细节中发生了什么,你就必须继续这项工作,但是你可以通过运行程序来看到发生了什么(可能把
usleep(10000)
放在某个地方,这样你就可以真正看到输出)。它将编写一个死记硬背的字符串“
Corsix!


编写这样的程序非常容易:一旦您决定了算法的工作方式,就很容易生成一个字符串,比如
,这使得算法生成您想要的内容,但是进行逆向工程要困难得多。

虽然这段代码不符合标准,但gcc将编译它,并且输出是一致的通过我对代码的分析。遗憾的是,如果没有更多的上下文,我无法真正解释输出。如果我忽略了退格,输出看起来像这样:

C!o!r!s!i!...
要分析代码,我们将从格式化代码开始:

#include <stdio.h>

char* _ ="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";

int main(int l){
    for(l+=7; l != putchar(010); ++l); // 010 = 8 -> backspace char
    if(*(++_))
        main(
            *_ != 88 ? // *_ != 'X'
                ( putchar(*_ ^ 073) | putchar(33) ) & 1 : // 33 = '!'
                0xffff2a8b);
}
这开始类似于我们前面看到的输出。让我们继续分析一些更有趣的行:

for(l+=7; l != putchar(010); ++l); // 010 = 8 -> backspace char
这一行的要点是输出一系列的退格。如果l等于1,它将只输出一个退格。但是如果它等于其他值,它会在卸载一卡车的字符时变得疯狂。行为取决于main的调用方式。在启动时,它似乎总是用值1调用(不知道为什么)

现在让我们看看递归主调用的组件

( putchar(*_ ^ 073) | putchar(33) ) & 1 : // 33 = '!'
这是第一个可能的分支。首先,它输出一个XORed字符,然后输出一个“!”字符。如果您查看33的位模式,您会注意到(x | 33)&1将始终计算为1。因此,在本例中,我们只在for循环中输出一个退格字符

另一方面,第二个分支有点棘手,因为传递给main的值不是1。如果仔细查看程序的输出,您会注意到它确实在字符串中的某个位置输出了大量的backspaces。没有上下文,我无法真正说出目标是什么

现在我们有了所有的部分,让我们重写代码:

#include <stdio.h>

#define BIG_CONSTANT 42 // Not the actual value.

int main () {
    char* str = "cCorsixcxCorsicixCorscsixCorcrsixCocorsixCcCorsixc";

    putchar(8);

    char* c = str;
    while (*c != '\0') {

        if (*c != 'c') { // 'X' ^ 073 = 'c'
            putchar(*c);
            putchar('!');
            putchar(8);
        }
        else {
            for (int i = 0; i < BIG_CONSTANT; ++i)
                putchar(8);
        }
        c++;
    }
}
#包括
#定义大常量42//而不是实际值。
int main(){
char*str=“ccorsixcorsixcorscisxcorscisxcorscisxocorsixccorsixc”;
putchar(8);
char*c=str;
而(*c!='\0'){
如果(*c!='c'){/'X'^073='c'
putchar(*c);
putchar(“!”);
putchar(8);
}
否则{
对于(int i=0;i
我的C有点生疏了,所以这可能无法编译/运行。它应该仍然可以让您对正在发生的事情有一个很好的了解


编辑:我发布答案时有点晚了,我刚刚意识到我的控制台是以文字形式打印退格,而不是仅仅删除字符。这就是为什么我对输出有点误解。因此,正如公认的答案所说,如果你真的正确处理退格,它会打印Corsix!

Se弗雷德·拉森:我在谷歌上搜索过,但找不到任何相关信息。你能和我分享一些信息吗?你是在问
main
是否可以打电话给
main
,还是在问关于该代码的解释?这是两个完全不同的问题。请编辑使标题与问题相符。@Chan:@C韩:代码是故意编码的,因此无法读取。我们可以努力阅读,但除非你是原始作者,否则它永远不会绝对清晰。@Chan现在我再看一看,我想我在某个地方犯了错误。如果你看C代码,所有的“!”字符都会被输出的退格删除就在这之后。由于行为相当琐碎,我认为分析才是真正重要的,所以我不会追查问题。
#include <stdio.h>

#define BIG_CONSTANT 42 // Not the actual value.

int main () {
    char* str = "cCorsixcxCorsicixCorscsixCorcrsixCocorsixCcCorsixc";

    putchar(8);

    char* c = str;
    while (*c != '\0') {

        if (*c != 'c') { // 'X' ^ 073 = 'c'
            putchar(*c);
            putchar('!');
            putchar(8);
        }
        else {
            for (int i = 0; i < BIG_CONSTANT; ++i)
                putchar(8);
        }
        c++;
    }
}