실행 중인 프로그램에 비트 플립 오류를 삽입하고 싶습니다. 이를 위해 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
값 eip
은0x804af34. 따라서 비트 연산을 수행하면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