[英]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
等於0x63
( 99
),然后找到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.