c++ 과 c는 한끗차이라.. 배우면서 영 흥미는 안가는데
특히 비트 계산과 그놈의 레지스트리 설정이 뭐같다
qt 개발 ide가 워낙 편해서 ui 쪽은 내려놓고 써도 되는 툴임. 문제는 windows 환경에선 안돌아간다 ㅋㅋ
디버그 툴 , 스택에서 특히 주소값들이 바이너리값으로 표현됨
분석툴로 실행파일을 돌리면 어셈블리어 기반으로 되어있음.
32bit 레지스트리를 로드했을때 (eax,ebx) 어셈블리는 메모리주소 = 4byte(8개비트)크기로 나타내고 있다
현대 x86프로세스 2^8 메모리 주소까지 접근가능 설계
메모리 주소 / 포인터의 경우에도 0xFFFFFFFF / 32비트 /즉 4바이트
메모리 주소를 나타내는 게 포인터 ,혹은 데이터라고 말함
난독화되어있으면 주소값을 확인하고, 각 함수들을 실행시켜가며 패턴을 보고 분석해야하는 경우도 있나봄. (리버싱은 정말 어렵구나...🤮)
어셈블리 기초
register를 하기전 cpu를 알아야 함
register : 메모리 공간. 데이터 임시 저장 공간
32bit cpu == regsiter 공간 32bit
intel CPU는 공간이 뒤에서 할당 (리틀 엔디언)
대부분은 빅엔디언 방식.
eax
산술(덧셈 곱셈 나눗셈 등) 논리연산을 수행함
함수의 반환값이 이 레지스터에 저장됨
모든 산술 명령은 eax 레지스터를 사용하며
함수의 반환값이 eax레지스터에 저장됨
즉 호출 함수의 성공/실패 여부를 쉽게 파악하고 반환값을 쉽게 얻어올 수있다
ebx
순수저장공간
esi레지스터나 edi 레지스터와 결합될 수있고, 이 ebx 레지스터는 메모리 주소를 저장하기 위한 용도
ecx
카운터 레지스터
주로 반복 명령어 실행시 반복 카운터로 사용되는 레지스터
ecx레지스터에 반복할 횟수 저장한 후 , 반복작업을 수행함 (증감자)
edx
eax와 함께 쓰이고, 부호 확장명령등에 쓰인다
큰 수의 곱셈 또는 나눗셈 연산이 이루어질 때 edx 레지스트리 사용,
eax레지스트리와 함께 쓰임
연산값이 32bit 이상인 경우 추가 할당됨
나누기 연산시 몫 eax 나머지 edx 저장
esi
문자열 데이터의 출발지 주소를 담음 (원본주소)
문자열 복사시사용.
데이터를 조작, 복사시 소스 데이터의 주소가 저장됨
edi
문자열 데이터의 목적지 주소를 담음 (복사 주소)
esi 레지스트리와 비슷, 복사시의 목적지의 주소가 저장됨
ebp
함수 선언시 주소값 저장
스택 프레임 시작 지점주소 (스택의 가장 윗부분. 처음)저장됨
ebp 레지스트리는 현재 사용되는스택 프레임이 소멸되지 않는 한 값이 변화하지 않는다
esp
변수 선언시 주소값 저장
스택 프레임 끝 지점 (스택의 가장 아랫부분. 마지막) push, pop 명령에 의해 esp 값이 4byte씩 변화
2bit 기준, 빅엔디안으로 소스코드 분석하면 레지스트리의 경우 반대로 찍힌다! (역순으로 기록된다)
참고
2
라는 변수 -> 0x00000002
이 데이터를 ebx가 나타내고 있는 메모리 주소에 복사함.mov DWORD PTR [ebx], 2
데이터 2를 4바이트 크기로 ebx가 가리키는 메모리 주소에 복사한다.byte order 를 만들어주는 함수
서로 다른 데이터 저장방식을 가진 cpu끼리 통신시 서로 다른 값을 주고 받을수 있기에, 설정함.
데이터 통신시 명시적으로 네트워크 byteOrder 를 따르도록 데이터 byteOrder 를 변경함.
네트워크 byte order 에서는 주로 빅엔디안 방식으로 따른다고 함
htons - 2byte 데이터/ short integer/ 호스트바이트 순서를 빅엔디안 바이트순서로 변환
#include <netinet/in.h>
unsigned short int htons(usigned short int hostshort);
htonl - 4byte /long integer/호스트 바이트순서를 빅엔디안 바이트 순서로 변환
#include <netinet/in.h>
unsigned short int htonl(usigned long int hostshort);
ntohs - 2byte/short integer /호스트 바이트 순서를 리틀엔디안 바이트 순서로 변환
#include <netinet/in.h>
unsigned short int ntohs(usigned short int hostshort);
ntohl - 4byte/long integer / 호스트 바이트 순서를 리틀엔디안 순서로 변환할때 쓰인다.
#include <netinet/in.h>
unsigned long int ntohl(usigned long int hostshort);
0x1234
>> 0x12
0x34
0x1234
>> 0x34
0x12
#include<stdio.h>
int sum (int a, int b){
return a + b;
}
int main(int argc, char* argv[]){
sum(5,4);
return 0;
}
00401068 |. 6A 04 PUSH 4
0040106A |. 6A 05 PUSH 5
0040106C |. E8 94FFFFFF CALL Consolas.00401005
00401071 |. 83C4 08 ADD ESP,8