簡體   English   中英

如何確定此函數將返回什么輸入呢?

[英]How does one determine for what input this function will return true?

一個喜歡編碼的朋友為我提供了這個小小的思想練習。

一個字符串應該通過什么字符串,以便在處理str == check_string

這對我來說似乎很有趣,但是我看不到如何推斷要使用的字符串。

bool func(char str[3])
{
    char check_string[3] = {0x63, 0x69, 0x71};
    int i = 0;
    int j = 42;

    for (i = 0; i < 3; i++, j += 3) {
        str[i] ^= j;
    }

    return strncmp(str, check_string, 3);
}

如何處理呢? 這是一個技巧問題嗎?

記事本中的試運行告訴我,當您進入strncmp調用時, str的狀態將為:

str[0] = str[0] ^ 42
str[1] = str[1] ^ 45
str[2] = str[2] ^ 48

假設比較是與0x63, 0x69, 0x71比較0x63, 0x69, 0x71則對於str[0] ^ 42等於0x6399 ),然后找到X使得:

X ^ 42 == 99

請注意, XOR是一個有趣的操作,您只需重新應用它即可將其求反(而加法則通過減法來逆轉,而乘以除法則是逆向):

99 ^ 42 == 73

因此輸入str[0]必須為73。

重復str[1]str[2]過程如下:

str[0] = (  99 ^ 42 ) = 73 = 'I'
str[1] = ( 105 ^ 45 ) = 68 = 'D'
str[2] = ( 113 ^ 48 ) = 65 = 'A'

因此,將對輸入字符串“ IDA”進行處理,以使兩個字符串相等。

我不知道IDA的意義是什么,請問您的朋友-這可能是對強大的IDA拆卸工具的引用。

我們可以蠻力地使用它,我們嘗試使用所有可能的長度為3字符串:

#include <bits/stdc++.h>

bool func(char str[3])
{
    char check_string[3] = { 0x63, 0x69, 0x71};
    int i = 0;
    int j = 42;

    for (i = 0; i < 3; i++, j += 3) {
        str[i] ^= j;
    }

    return strncmp(str, check_string, 3);
}

int main(){
    for(int i=0;i<200;i++){
        for(int j=0;j<200;j++){
            for(int k=0;k<200;k++){
                char s[3]={i,j,k};
                if(!func(s)) printf("%c%c%c\n",i,j,k);
            }
        }
    }
}

輸出: IDA

解決方案是對檢查字符串應用相同的XOR操作以給出相反的結果。 干得好 ...

#include <stdio.h>
#include <string.h>

int func(char str[3])
{
    char check_string[3] = { 0x63, 0x69, 0x71};
    int i = 0;
    int j = 42;

    for (i = 0; i < 3; i++, j += 3) {
        str[i] ^= j;
    }

    return strncmp(str, check_string, 3);
}

void solv(char str[3])
{
    static char check_string[3] = { 0x63, 0x69, 0x71};
    int i = 0;
    int j = 42;

    for (i = 0; i < 3; i++, j += 3) {
        str[i] = check_string[i];
        str[i] ^= j;
        printf("%2.2X --> %2.2X j=%2.2X/%d\n",check_string[i],str[i],j,j);
    }
}

int
main(int argc,char **argv)
{
    char sol[3];
    int val;

    solv(sol);
    printf("solv: %2.2X %2.2X %2.2X\n",sol[0],sol[1],sol[2]);

    val = func(sol);
    printf("func: %2.2X %2.2X %2.2X %d\n",sol[0],sol[1],sol[2],val);

    return 0;
}

如何處理呢?

您需要輸入一個等於本地check_string[]的字符串,以便strncmp()返回0

現在,要了解字符串需要是什么,您可以通過以下方式對其進行反向工程

  • 通過相同的for循環運行check_string[]以獲取相反的結果。

  • 然后將其用作輸入參數。

這是執行此操作的代碼:

#include <stdio.h>
#include <string.h>

int func(char str[3]) {
    char check_string[3] = { 0x63, 0x69, 0x71};
    int i = 0;
    int j = 42;

    for (i = 0; i < 3; i++, j += 3) {
        str[i] ^= j;
    }
    return strncmp(str, check_string, 3);
}

/*
    Function: reverse_xor()
    Use: reverse_xor(c_str);

    It applies XOR to c_str
    so that when we pass it
    to func(), the XOR applied
    there will invert it and
    c_str == check_string. 
*/
void reverse_xor (char str[3]) {
    static char check_string[3] = {0x63, 0x69, 0x71};
    int i = 0;
    int j = 42;

    for (i = 0; i < 3; i++, j += 3) {
        check_string[i] ^= j;

        // apply XOR on check_string and assign it to the passed argument
        str[i] = check_string[i];
    }
}

//============================================
int main(void) {
    char sol[3];

    revers_xor(sol);

    printf("%c\n",sol[0]);
    printf("%c\n",sol[1]);
    printf("%c\n",sol[2]);

    int val = func(sol);
    printf("%d\n",val);

    return 0;
}

輸出:

I
D
A

0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM