GDB를 사용하여 레지스터에서 산술 연산을 어떻게 수행할 수 있나요? [폐쇄]

GDB를 사용하여 레지스터에서 산술 연산을 어떻게 수행할 수 있나요? [폐쇄]

실행 중인 프로그램에 비트 플립 오류를 삽입하고 싶습니다. 이를 위해 gdb대상 프로그램에 중단점을 삽입하고 무작위로 선택된 레지스터에서 단일 비트를 뒤집습니다. Ubuntu에서 이 명령을 실행하려고 하면 gdb다음 오류가 발생합니다 $eip.

(gdb) info r
...
eip        0x804af59        0x804af59 <main+37>
...

(gdb) p/a $eip
$4 = 0x804af59 <main+37>

(gdb) set $eip = $eip ^ 0x800
argument to arithmetic operation not a number or boolean

(gdb) set $eax = $eax ^ 0x1
(gdb)

이해가 안 돼요. 이것이 GDB의 버그인가요? 또는 문법적 오류.

다음 레지스터를 변경하려고 할 때만 오류가 발생합니다: %eip, %esp%ebp. 목록에서 우리는 레지스터의 내용을 변경할 때 아무런 문제가 발생하지 않음을 알 수 있습니다 eax.

추가 정보...

열악한 환경에서 작동하는 안전이 중요한 시스템에서 시스템은 단일 오류 롤오버(예: 단일 오류 롤오버)와 같은 소프트 오류에 더 취약합니다.남동대학교) 약간 뒤집힌 것과 같습니다. 이러한 맥락에서 연구자들은 이러한 오류를 감지하고 시스템의 신뢰성을 유지하기 위한 다양한 기술, 즉 내결함성 기술을 개발했습니다. 이러한 기술을 평가하기 위한 가장 효과적인 접근 방식은 오류 주입입니다. 런타임 시 아키텍처의 가장 중요한 부분에 오류를 삽입한 다음 강화된 시스템을 모니터링하여 사용하는 내결함성 기술의 오류 적용 범위를 평가해야 합니다. 일반적으로 소프트 오류를 ​​시뮬레이션하려면 결함 주입을 사용해야 합니다. 나는 eip레지스트라의 업무가 무엇인지, 그것이 프로그램의 제어 흐름에 얼마나 민감한지 잘 알고 있습니다 .

사용된 GDB 버전은 다음과 같습니다.

gdb --version
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.

gdb 세션의 일부 출력:

(gdb) p $eip
$1 = (void (*)()) 0x804af34 <main>

(gdb) ptype $eip
type = void (*)()
(gdb) 

그리고 void로 변환 하면 int오류 없이 잘 작동하는데,하지만 결과는 이상적이지 않은 것 같아요, eip의 내용을 0x1과 XOR하여 단일 비트만 토글하려고 하기 때문입니다!

(gdb) set $eip=*(int *) $eip ^ 0x1
(gdb) p $eip
$2 = (void (*)()) 0x4244c8c

eip0x804af34. 따라서 비트 연산을 수행하면0x1, 결과는 다음과 같아야 합니다.0x804AF35아니요0x4244c8c? !

(gdb) p $eip
$8 = (void (*)()) 0x804af34 <main>
(gdb) p *(int *) ($eip)
$9 = 69487757
(gdb) p *(int *) $eip ^0x1
$10 = 69487756
(gdb) p/a *(int *) $eip ^0x1
$11 = 0x4244c8c
(gdb) 

답변1

(int)int에 대한 강제 포인터를 사용해야합니다 . 향후 테스트에서는 다음을 수행해야 합니다.아니요메모리를 *가리키는 포인터를 역참조하는 데 사용됩니다 .$eip

(gdb) p/x (int)$eip  
$4 = 0xf7eb9810
(gdb) p/x (int)$eip^1
$5 = 0xf7eb9811
(gdb) set $eip = (int)$eip^1
(gdb) p/x (int)$eip
$6 = 0xf7eb9811
(gdb) set $eip = (int)$eip^0x800
(gdb) p/x (int)$eip
$7 = 0xf7eb9011

관련 정보