쉘 변수와 바이너리 파일의 XOR

쉘 변수와 바이너리 파일의 XOR

명령줄 입력에서 읽은 쉘 변수에 비밀번호가 저장되어 있습니다.

dd또한 ( 및를 사용하여 생성된) 파일에 키 파일이 저장되어 있습니다 /dev/urandom.

내 하드 드라이브의 암호를 해독하려면 두 가지 모두를 요구하고 싶기 때문에 두 가지를 XOR하여 파일에 저장하고 키로 사용하고 싶습니다.

그러므로 가장 간단한 방법이 무엇인지 알고 싶습니다.

xxd허용된다면 완벽하게 맞을 텐데 -b동시에 -p그렇지 않습니다...


편집 : 나는 그것을 사용할 것이다https://github.com/xavierm02/combine-keys

답변1

쉘은 비트 연산을 처리할 수 있지만 심각한 처리의 경우에는 다음과 같습니다.몹시느리고 한 번에 20자리 정도 이상의 숫자를 처리할 수 없습니다. 아직:

sh <<\CMD 
    printf 'printf "%%b" "\\0$((%04o^04))"'  "'a" |\
    . /dev/stdin
CMD

#OUTPUT
A

bc나는 과거에 바이너리로 바이트를 잡는 데 사용했기 때문에 귀하의 질문으로 인해 인터넷 검색을하게되었습니다 ...

GNU bc의 배타적 논리합(XOR)

인터넷을 통해 이 질문에 대한 답을 찾았다면 아마도 C ^연산자에 해당하는 bc 연산자를 찾고 있을 것입니다.

충격적인 사실: 에는 그런 것이 존재하지 않습니다 bc. 에서 bc위쪽 화살표 연산자는 정수 지수화에 사용됩니다. 즉, 2^x비트 2가 뒤집힌 x가 아니라 2의 거듭제곱을 반환합니다. XOR, AND, OR 및 몇 가지 더 이국적인 친척에 대한 비트 연산자에 해당하는 것을 찾고 있다면 이 사이트의 logic.bc와 이들 각각을 수행하는 함수가 포함된 친척을 확인하십시오.

XORif 문에 넣을 논리문(예: logic &&and ) 을 찾고 있다면 조건을 대괄호로 묶어서 ||사용해 보세요 . !=예:

c=0;if((a==1)!=(b==2)){c=3}

a가 1이거나 b가 2인 경우 c를 3으로 설정하지만, a가 1이고 b가 동시에 2인 경우에는 설정하지 않습니다.

(옛날에는 이것이 logic.bc xor() 함수 내부의 비밀이었지만 더 빠른 알고리즘으로 대체되었습니다.)

위 내용은 FAQ에서 발췌한 내용입니다 bc. logic.bc위에 언급된 함수에는 찾고 있는 논리가 포함되어 있습니다 bitwise. 찾을 수 있습니다여기. 설명:

수행할 수 있는 다양한 기능 모음비트별AND, OR, NOT 및 XOR과 같은 함수. 전혀 지원하지 않았던 이 파일의 이전 버전과 달리 음수에 대해 2의 보수를 사용합니다. 여기에 있는 일부 기능은 이 파일의 일부로 초기화되는 전역 비트폭 변수를 사용하여 대부분의 컴퓨터에서 발견되는 바이트/워드 크기를 에뮬레이션합니다. 이 변수가 0으로 설정되면 무한 비트폭이 가정됩니다. 숫자의 보조 부동 소수점 표현이 생성된 것으로 의심되는 경우 많은 함수에서 경고를 표시합니다. 예:

1.1111... is an SFPR of10.0000...;`

이러한 경고는 전역 변수를 (기본값은 1) sfpr_warn로 설정하여 비활성화할 수 있습니다.0

  • 고정된 단어 크기
  • 무한한 단어 크기
  • 공통 비트별
  • 2의 보수
  • 비트 이동
  • 그레이 코드
  • '곱셈'
  • 부동 소수점
  • 부동 소수점 '곱셈'
  • 그레이 코드 + 부동 소수점

답변2

저는 C 바이너리를 사용했습니다.

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "No argument given.\n");
        exit(1);
    }
    char *filename = argv[1];

    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Could not open given file.");
        exit(1);
    }
    int c1;
    int c2;
    do {
        c1 = fgetc(stdin);
        c2 = fgetc(file);
        if (c1 == EOF) {
            while (c2 != EOF) {
                printf("%c", c2);
                c2 = fgetc(file);
            }
            break;
        } else  if (c2 == EOF) {
            while (c1 != EOF) {
                printf("%c", c1);
                c1 = fgetc(stdin);
            }
            break;
        }
        int c = c1 ^ c2;
        printf("%c", c);
    } while (true);

    exit(0);
}

답변3

SH에서 뭔가가 거의 작동하고 있는데 너무 느립니다.

#!/bin/sh

small_hex_to_bin() {
    hex=$1
    hex_length=${#1}
    bin=$(echo "ibase=16;obase=2;$hex" | bc)
    bin_length=$((4*$hex_length))
    bin=$(printf %0*d $bin_length $bin)
    echo $bin
}

hex_to_bin() {
    hex=$1
    hex_length=${#hex}
    for i in $(seq 1 $hex_length); do
        hex_digit=$(expr substr $hex $i 1)
        bin_digits=$(small_hex_to_bin $hex_digit)
        echo -n $bin_digits
    done
    echo ""
}

bin_to_hex() {
    bin=$1
    hex=$(echo "ibase=2;obase=10000;$bin" | bc)
    echo $hex
}

char_to_hex() {
    char=$1
    hex_lower=$(printf %x \'$char\')
    hex=$(echo $hex_lower | tr '[:lower:]' '[:upper:]')
    echo $hex
}

char_to_bin() {
    char=$1
    hex=$(char_to_hex $char)
    bin=$(small_hex_to_bin $hex)
    echo $bin
}

string_to_bin() {
    s=$1
    l=${#s}
    for i in $(seq 1 $l); do
        char=$(expr substr $s $i 1)
        bin=$(char_to_bin $char)
        echo -n $bin
    done
    echo ""
}

file_to_bin() {
    filename=$1
    hex_spaces=$(xxd -u -p $filename)
    hex=$(echo $hex_spaces | tr -d '\n' | tr -d ' ')
    bin=$(hex_to_bin $hex)
    echo $bin
}

min() {
    if [ $1 -ge $2 ]; then
        echo $2
    else
        echo $1
    fi
}

bit_xor() {
    if [ $1 -eq $2 ]; then
        echo 0
    else
        echo 1
    fi
}

xor() {
    b1=$1
    b2=$2
    l1=${#b1}
    l2=${#b2}
    l=$(min $l1 $l2)
    for i in $(seq 1 $l); do
        c1=$(expr substr $b1 $i 1)
        c2=$(expr substr $b2 $i 1)
        c=$(bit_xor $c1 $c2)
        echo -n $c
    done
    next_i=$(($l + 1))
    if [ $l -ne $l1 ]; then
        for i in $(seq $next_i $l1); do
            c1=$(expr substr $b1 $i 1)
            echo -n $c1
        done
    fi
    if [ $l -ne $l2 ]; then
        for i in $(seq $next_i $l2); do
            c2=$(expr substr $b2 $i 1)
            echo -n $c2
        done
    fi
    echo ""
}

#stdin=$(cat)
#file=$(cat $1)
#hex_to_bin $1
file_to_bin $1

관련 정보