2014-07-05 5 views
0

char 배열을 초기화하고 싶지만,이 과정에서 프로그램이 충돌합니다. 여기char [] 초기화 실패, esi 잘못된 값 포함

void kernelEnteredMsg() { 
    char str[] = "Kernel successfully entered!"; 
} 

를 분해입니다 : 여기 내 코드는이 0x402000으로 함께 ESI를로드 왜 이해가 안

push ebp 
mov ebp,esp 
push edi 
push esi 
push ebx 
sub esp,byte +0x30 
lea edx,[ebp-0x2d] 
mov ebx,0x402000 ; load an address outside my data segment 
mov eax,0x1d 
mov edi,edx 
mov esi,ebx ; move this address to edi 
mov ecx,eax 
rep movsb ; here the programm crashes 
add esp,byte +0x30 
pop ebx 
pop esi 
pop edi 
pop ebp 
ret 

. 그러나 이것은 오류를 일으키는 것 같습니다. 누군가 여기서 일어나는 일과 그것을 고치는 방법을 설명 할 수 있습니까?

추신 : "Kernel successful entered!" 이진 파일에서 0x1000에 있습니다.

C 코드 :

void kernelEnteredMsg(); 

void entryPoint() { 
    kernelEnteredMsg(); 
} 

void kernelEnteredMsg() { 
    char str[] = "Kernel successfully entered!"; 
    int size = 28; 
} 

호출 어셈블리 코드 :

extern _entryPoint 
global _main 
section .text 
_main: ; start of kernel 
nop 
; setup ds, es, ss and gs 
mov ax, 16 
mov ds, ax 
mov es, ax 
mov ss, ax 
mov sp, 0x4000 
mov ax, 24 
mov gs, ax 
mov [gs:0], dword 0x07690748 ; test graphics 
call _entryPoint ; enter kernel C code 
jmp $ 
+3

격리되어 있으면이 C 코드로 인해 컴파일러/링커/런타임이 손상되지 않는 한 충돌이 발생할 수 없습니다. 코드의 다른 곳에서 정의되지 않은 동작을 호출해야합니다. –

+0

@OliCharlesworth 필요한 코드는 얼마입니까? – kaetzacoatl

+2

@kaetzacoatl 그것은 "얼마나"에 관한 질문이 아닙니다 ... 우리는 충돌을 일으키는 코드가 필요합니다. –

답변

3

이 코드는 문자 배열이 "CONST"되지 않기 때문에, 로컬 스택에 텍스트 섹션에서 문자열을 복사하지 . 이것은 문자열을 수정하지 않아도되는 간단한 해결책을 제공 할 수 있습니다. 단지 const char로 변경하십시오.

0x402000과 함께 esi가로드되는 이유를 알 수 없습니다.

ESI는 문자열 복사 명령 'rep movsb'의 원본이며, EDI는 대상입니다. 주소는 PE 파일의 IMAGE_BASE + SECTION (IIRC)에 의해 생성됩니다 (PE라고 가정). 파일에 FILE_ALIGN 및 SECTION_VIRTUAL_ADDRESS가 있으므로 섹션은 파일의 0x1000 위치에 이 될 수 있습니다 (FILE_ALIGN) 및 메모리 (VIRTUAL_ADDRESS) 0x2000에서 IMAGE_BASE + VIRTUAL_ADDRESS = 0x402000이됩니다.

이를 표시 할 CFF 탐색기처럼 (http://www.ntcore.com/exsuite.php) 을 체육 탐색기를 사용할 수 있습니다 (.BIN 그것이 unapplicable 수 있습니다 파일 않다면하지만 형식의 일종 가지고있다)

또 다른 가능성이있을 수 있습니다를 문자열 복사 명령의 잘못된 동작으로 이어지는 DF-Flag의 잘못된 상태입니다 (컴파일러가이 문제를 처리해야하므로 발생하지 않아야 함).

는 "UP"으로 문자열을 설정할 증가 [] 숯 STR 전 또는 __main 절차에

__asm__ ("cld"); 

삽입 시도.

+0

gcc에 데이터가 저장된 위치를 말할 수 있습니까? – kaetzacoatl

+0

gcc에서는 모르지만 PE 파일의 파일 섹션에는 임의의 이름과 속성이 있습니다. 일반적으로 .text-section 또는 .rdata-section은 읽기 전용이며 상수에 사용됩니다 (내 대답의 첫 번째 단락 참조). 만약 당신이 char str []을 전역 변수로 선언한다면, 그것은 읽기 - 쓰기 인 .data-section에 놓여 져야하고 따라서 스택에 복사 할 필요는 없다. 섹션 이름은 단지 규칙이며 사용 된 컴파일러 (및 버전)에 따라 변경 될 수 있습니다. – zx485

+0

음, 한 번 추가. 섹션에 관한 모든 부분은 환경 (OperatingSystem)에 따라 달라지며, 섹션이 디스크에서 메모리로로드되기 때문입니다. 예를 들어, 간단한 부트 로더 또는 커널을 직접 작성하려고 시도하고 ds, es, fs, gs를 수동으로 설정하면 수동으로해야합니다. 섹션이 아직 없기 때문입니다 (gcc). 실제로 존재하는 것과 꼭 일치하지 않는 (특정) 환경을 가정합니다. – zx485