어셈은 하고있눈데
리버싱하려면 프로그래밍 언어 다두룰줄알아야하나여?
익명(122.32)
2015-04-26 01:49
추천 0
댓글 29
다른 게시글
-
이거 아는 사람 있냐?(네트워크 관련) [10]수크라제(inviolable) | 15.04.26추천 0
-
[오늘의 컬처쇼크] 전파 도청(TEMPEST)의 세계 (예:키보드 도청) [2]ㅅㅅㅅ(125.128) | 15.04.26추천 0
-
[토막 C상식] calloc은 왜 메모리를 0으로 초기화할까? [4]ㅅㅅㅅ(125.128) | 15.04.26추천 1
-
엔더톤 책이나 읽어보고 이산수학,수리논리학이 쉽다는 개소리 하는거지 [1]익명(175.223) | 15.04.26추천 1
-
학벌도 병신같은 애들이 여기서 지랄 하는거 보면 기가안찬다 [3]익명(175.223) | 15.04.26추천 0
-
소켓으로 문자열 배열 보낼땐 어떻게함? [8]안드의노예(118.35) | 15.04.26추천 0
-
c언어 질문 [9]익명(59.22) | 15.04.26추천 0
-
코딩문제중에 정답률 1프로짜리 문제 있습? [2]ㅁㄴㅇ(175.116) | 15.04.26추천 0
-
은행원의 반올림 알고리즘(Banker's Rounding) [5]ㅅㅅㅅ(125.128) | 15.04.26추천 1
-
전자전기학과가서 [1]ㅁㅇ(110.11) | 15.04.26추천 0
리버싱의 대상이 되는 프로그램의 언어는 어느정도 알아야 됨
그래야 어셈 코드를 해석해서 해당 언어의 구조를 식별할 수 있으니깐
아니. 언어는 일단 대중적인 C/C++만 해도 일단은 괜찮음. 그리고 이후로는 윈도우 API, MFC 등을 추가적으로 공부하고 PE 구조, 윈도우 커널 구조와 x86 Architecture에 대한 심화 학습 순으로 진행.
내 "아니"는 ㅁㄴ에 대한 답이 아니라 글쓴이 글에 대한 답.
프로그래밍 언어 다다익선으로 많이 알면 알수록 좋겠지만 새로운 언어가 나오면 그 때 새로 익혀도 됨. 어차피 언어는 한두개 익히면 금방 배운다.
ㅅㅅㅅ형님 답변이 예전에 '게임개발자'라는 분과닮았네여 친절한듯
ㅋㅋㅋ
사실 function call이랑 pointer 정도만 알면 뭐가 좀 보이기 시작하는듯
cdcel stdcall fastcall 이거 말하시는건가요?
나 같은 사람이 프갤에 또 있었나 보네. 그러고 보니 며칠 전에도 ㅋㅋㅋㅋ라는 애가 내가 게임개발자라고 글 올린 적이 있었지.
그분도 존나 천재였던걸로기억
사실 리버싱 관점에서 어셈에서 제일 중요하게 봐야할 건 함수 부분임. 까놓고 말해서 함수 부분 이해만 해도 어셈의 반은 이해할 수 있어. CALL/RET 구문의 내부 동작, 스택 프레임(Stack Frame)에 대한 이해와 __cdecl __stdcall __fastcall 같은 Calling Convention을 봐두면 함수는 마스터임.
그런데 제가 위에 calling convetion그거 어떻게 돌아가는 리버싱한거 몇개보여주던데 진짜 농담아니라 별거없더라구요 책에 예제로1장반정도 예를 들어서 설명한것뿐인데 원래 분량은 많은거겠죠? 이책이 간단하게 설명한거맞죠?
뭐 존나 복잡하게 씨부렸지만, CALL과 RET(RETN이라고도 씀)이라는 어셈 명령어와, 인자를 어떻게 넘기는가(스택 이용), 반환 값은 어떻게 전달하는가(EAX 레지스터 이용), 함수 내부에서 지역 변수를 사용하기 위한 스택 프레임(Stack Frame)(다른 말로 activation record(활성 레코드)라고도 부름), 인자를 넘길 때 사용한 스택 공간을 누가(호출한 코드/함수 코드 내부) 정리하는가에 대한 호출 규약(Calling Convention)들만 이해하면 함수는 끝임.
진짜 별거 없어. 함수 파트에서 제일 어려운 건 스택 프레임이야.
그럼두개만 물어볼게요 예전에 리버싱보다가 스택에 ebp여러개 push해서 매개변수 지역변수 구분하던데 여러개 push 가능한가요 ebp를 ... 그리고 esi edi이거 언제 쓰는지 진짜 이해가 안되여 구글링해도 딱히 얻은것도없고...
ebp는 한개만 push하지 않나... esp를 ebp에 옮기고 스택 공간 확보해서 +쪽으로 가면 매개변수 -쪽으로 가면 지역변수인 걸로 알고있는데
보통 EBP는 스택 프레임 형성 과정에서 한번만 푸시하는데... 목적은 오리지널 EBP 값을 스택에 백업하려고. 여러번 푸시하는 거면 그냥 스택에 쓰레기 값 채워서 지역 변수를 위한 공간을 만드는 게 목적이었을 듯. 근데 그건 보통 SUB 명령어로 ESP 값을 낮추는 방식으로 하는 게 일반적임.
예전에본예제가 어떤거였냐면 매개변수삽입하고 ebp삽입하고 지역변수삽입하고 그 ebp를 중심으로 + - 해서 왔다갔다 거렸던걸로 기억하는데영...
그리고 x86의 10개 레지스터 중에서 EAX/EBX/ECX/EDX/ESI/EDI 이렇게 6개가 범용 레지스터임. 아무렇게나 막 써도 돼. 다만 일부 명령어에서 특수한 용도로 사용될 때도 있는데, ESI/EDI 같은 경우 문자열 관련 명령어(예: LODSB, STOSB)에서 그 이름대로의 용도로 쓰여.
그렇군요 esi,edi는 보통 문자열 오프셋값을 삽입하더라구요
ㅇㅇ 문자열 관련 어셈 명령어에서 ESI/EDI만을 쓰기 때문에 관습인 듯.
어셈도 밑바닥부터 제대로 이해하려면 16비트 어셈부터 시작해야 돼. 그래야 세그먼트 레지스터가 왜 나온 건지 이해하게 됨.
실제모드 말하시는건가요? 예전에 게임개발자님한테 엄청 붙들려서 실제모드 세그먼트,도스 부터 보호모드 세그먼트까지 설명은 들은적있어요ㅋㅋ
ㅇㅇ 세그먼트 레지스터의 시작은 16비트 시절 16비트만으로는 64KB 메모리 이상을 표현할 수 없어서 궁여지책으로 도입된 거임. 64KB 한계를 없애려는 목적과 다중 프로그램을 동시에 메모리에 적재할 수 있도록 하기 위한 목적이 있음.
프로그램을 고정된 메모리 위치에 로드시키면 주소가 같은 두 프로그램을 실행할 수가 없겠지? 물론 도스 시절 멀티 태스킹이라는 개념이 없었다만 프로그램이 프로그램을 실행하는 경우는 많았으니깐. 그걸 해결하는 해법은 32비트 PE 포맷에서 하는 것처럼 Relocation Table(재배치 테이블) 형식으로 하는 방법이 있고, 또 쉬운 방법은 프로그램 상의 포인터를 모두 상대 주소 취급해 버리는 거임. CS, DS, SS라는 세그먼트 레지스터로 용도 별 메모리의 시작 주소를 가리키고 프로그램은 그 레지스터를 이용해서 상대 주소로만 접근하게 함으로써 마침내 다중 프로그램을 메모리 상에 적재(load)할 수 있도록 되었다.
아마 그때 설명들을떄 선형주소 물리주소 논리주소 이걸로 한글에 댓글64개 달렸던걸로 기억해요ㅎㅎ
저건 그냥 페이징으로 가상 메모리 구현하면서 나온 개념이잖아. 16비트 시절에도 논리 주소와 물리 주소까지는 있었어. Segment:Offset으로 표현된 주소가 논리 주소이고, 이걸 Segment×16+Offset해서 변환해서 구한 RAM 상의 바이트 위치가 물리 주소임. 32비트 보호 모드로 바뀌면서 가상 메모리가 구현되면서 이걸 3-Level로 구분해서 가상 메모리 체계 하에서 Segment를 계산하기 전의 가상 메모리 주소를 논리 주소, 그걸 Segment 적용해서 얻은 가상 메모리 주소를 선형 주소, 선형 주소를 페이지 테이블을 참고해서 RAM 상의 프레임 위치로 사상(map)시킨 것이 물리 주소임.
마자여 그떄 보호모드까지 얘기나오면서 가상기억장치나오고 해서 쭈욱 달렸던걸로 기억