안 쓰던 블로그
리버싱-전역/지역 변수 초기화 본문
아래 local 이라는 이름의 지역변수와 global이라는 이름의 전역 변수를 선언한 c언어 코드가 있다
#include "stdafx.h"
#include <stdio.h>
int global = 1;
int main(int argc, char* argv[]){
int local = 2;
return 0;
}
다음 C코드는 아래 같은 형태로 컴파일 된다
mov byte ptr [ebp-4], 1
mov byte ptr [ebp-8], 2
실제 컴파일된 코드는 다음과 같다
local 이름의 변수는 2번에 번역되었다
mov byte ptr [ebp-4], 2
그런데 global 이름의 변수는 분명 1로 초기화 했음에도 불구하고 코드가 존재하지 않다 1번
main 함수 주변에도 해당 코드가 없다
그러면 c코드를 이렇게 바꿔보자
#include "stdafx.h"
#include <stdio.h>
int global = 1;
int main(int argc, char* argv[]){
int local = global;
return 0;
}
main 첫 줄인 int local=global에 브레이크 포인트를 걸고 어셈블리 코드를 보면 이렇게 나온다
이걸 보면, global변수는 보통의 변수와 다르게 ebp레지스터를 매개로 하지 않고 직접 주소 0x00424a30로 매핑되어 있는 것을 알 수 있다
그리고 이 주소값을 eax레지스터로 한 번 옮겼다가 다시 ebp-4인 local변수 메모리 공간에 저장하는 과정을 거친다
0x00424a30번지의 값을 확인해 보면 01 00 00 00, 즉 데이터 1이 들어가 있는데,
두 번째 코드에서는 global변수를 1로 초기화하지 않았음에도 1로 초기화가 되었다
그 이유는 바로 global 변수가 데이터 세그먼트에 해당하는 변수이기 때문이다
데이터 세그먼트는 전역으로 선언된 변수들이 사용하는 메모리 공간이다
(메모리 구조 참고: https://foxtrotin.tistory.com/262)
정리하면 데이터 세그먼트로 맵핑된 변수인 global 변수는 특별히 코드를 통해 초기화되지 않고, 이미지(윈도우즈에서는 exe파일)가 메모리로 로드되는 순간 이미 global 변수에 해당하는 메모리도 같이 초기화된다
그런 이유로 컴파일된 코드에 global변수의 초기화 코드가 보이지 않았고, 특별히 초기화를 위한 코드가 필요 없는 것이다
'CTF > Reversing' 카테고리의 다른 글
어셈블리 코드 C코드로 변환하기 (0) | 2020.09.14 |
---|---|
Register (0) | 2020.09.01 |
[리버싱] 메모리 구조, 함수 호출 과정, Stack Frame (0) | 2020.08.30 |
abex crackme 3번-keyfile채우기 (0) | 2020.08.26 |
리버싱-분기문 우회 (0) | 2020.08.26 |