핸드백을 수동으로 만든 IAT를 재구축하면...

8605 단어 Binary
이 글은 Aizu Advent Calendar 2016 11일째 되는 글이다.
전날@RomTin, 다음날@je_je_la이었다.
내가 최근에 수동 하청에 도전했으니까 그거 말이야.
IAT(Import Address Table)는 재건축에 초점을 맞춘 기사이기 때문에 가방에서 무언가를 생략한다(혹은 많이 생략한다).
사용한 충전재는 upx(ver3.03)이고 x86에 구축된 PE 파일을 사용합니다.
사용된 디버거OllyDbg1.10에 플러그인 하나 적용OllyDump

수동 패키지 해제 프로세스


upx는 대체로 아래의 절차에 따라 마운트 해제합니다.

이번에는 빨간 테두리 이야기다.
그 이전 부분에 관해서는 구글에 가거나 참고 사이트를 보십시오.

덤프할 때까지


어쨌든 Hello World 프로그램을 준비해서 포장해.
OPE(Original Entry Point) 이후의 내용을 olly Dbg로 olly Dump로 메모리 덤프합니다.

IAT를 직접 재구성하기 때문에 Rebuild Import 검사를 취소합니다.
이 예에서 OPE의 오프셋은 0x1580이므로 modify를 1580으로 설정합니다.

IAT 정보


덤프된 PE 파일을 직접 실행하면 다음 오류가 발생합니다.

IAT 값이 잘못되어 발생한 오류입니다.
IAT는 PE 파일의 가져오기 함수 정보를 포함하는 테이블입니다.
실행하기 전에 포인터를 PE 파일의 함수 이름을 가리키고 이미지를 로드하면 함수의 실제 주소가 해결되며 IAT는 실제 주소로 덮어씁니다.함수 이름을 가리키는 포인터는 IMAGE -IMPORT_BY_네임이라고 합니다.
EP로 이동한 후 메모리를 덤프하면 IAT는 실제 주소를 유지한다.해당 IMAGEIMPORT_BY_NAME이 있어야 하기 때문에 그렇게 실행하면 오류가 발생합니다.따라서 IAT를 재구성하지 않으면 패키지 어셈블리를 완료할 수 없습니다.

IAT 재구축 방법


IAT 복구는 ImpREC특별 고양이 아직 57호 등의 툴을 통해 간단히 수행할 수 있습니다.
이번에는 도구에 의존하지 않고 Debuga와 바이너리 편집기에서 IAT 재구축을 진행합니다.
우선 덤프된 PE 파일의 IAT를 찾아낸다.
이렇게 하려면 먼저 설명자를 가져온 RVA(Relative Virtual Address) 값을 가져옵니다.
이 값은 NT 헤더가 있는 선택할 수 있는 헤더입니다.NT 헤더는 0x500x400x00(ascii의 "PE")에서 시작하는 248바이트의 이진법이다.선택한 헤더는 NT 헤더의 25 바이트부터 시작합니다.설명자를 가져오는 RVA는 작업 헤드의 105바이트에서 시작하는 4바이트입니다.
다음 그림에서 빨간색으로 둘러싸인 부분은 선택 헤더이고 파란색으로 둘러싸인 부분은 설명자를 가져온 RVA입니다.

즉, 이 예는 0x91dc이다.
그런 다음 Virtual Address 및 PointerToRawData 섹션을 참조하십시오.이것은 영역 제목이라고 불리는 40바이트 정보에 포함됩니다.UPX0, UPX1, upx로 포장.rsrc의 세 부분을 진행할 수 있기 때문에 각 부분에서 정보를 얻을 수 있습니다.Virtual Address는 13절 머리부터 4바이트, PointerToRawData는 마지막 4바이트입니다.
다음 그림은 UPPX0의 Virtual Address(파란색)와 Pointer ToRawData(녹색)입니다.빨간색은 전체 영역 제목입니다.

UPX0의 Virtual Address는 0x1000이고 Pointer ToRwoData도 0x1000이다.
이 요령 3개 구역의 값을 얻습니다.
영역/값
VirtualAddress
PointerToRawData
UPX0
0x1000
0x1000
UPX1
0x7000
0x7000
.rsrc
0x9000
0x9000
가져오기 설명자의 RVA가 0x91dc이기 때문입니다.rsrc에 속해야 합니다.
설명자의 오프셋을 입력하면 다음 공식을 사용하여 계산할 수 있습니다.
지역PointerToRawData+(RVA-부분 Virtual Address 가져오기)
이번에는 0x9000+(0x91dc-0x9000)=0x91dc.
파일의 시작 오프셋에서 이동한 위치에는 가져오기 설명자가 있어야 합니다. 여기서 시작 17 바이트에서 시작하는 4 바이트의 FirstThunk 값은 IAT의 오프셋입니다.
다음 그림의 파란색으로 둘러싸인 부분 0x9290은 IAT의 오프셋입니다.빨간색이 수입 설명서를 덮어쓰고 있습니다.

아래 빨간색으로 둘러싸인 부분은 IAT입니다.

PEiDPEView 등을 사용하면 PE 파일의 정보를 쉽게 얻을 수 있다.
그러면 각 4바이트 함수의 정보가 들어오고 있지만 현황이라면 실제 주소는 실행할 수 없는 상태로 들어간다.그래서 IMAGE.IMPORT_BY_네임으로 바꿔줄게.
이어서 IMAGEIMPORT_BY_NAME가 고정된 곳이 있기 때문에 필요한 것을 얻는다.
하지만 그 전에 어떤 이름을 어떤 이름으로 바꿔야 할지 몰라서 디버거에서 어떤 주소가 어떤 함수에 대응하는지 볼 필요가 있다.
그러면 최초 4 바이트의 0x76d38500을 예로 들어 고칩니다.
ollydbg를 사용하여 OPE 상태로 실행하고 View에서 Executable modules를 선택합니다.
그럼 각 모듈의 정보가 나올 것 같습니다.

이 중에서 관계가 있는 기본address 모듈(이번은 0x76d10000의 KERNEL 32)에서 Ctrl+N 또는 오른쪽 단추 메뉴에서 View names를 선택하십시오.
그리고 내보낸 함수 일람표가 나와서 일치하는 주소를 찾습니다.
Address가 적힌 곳을 클릭하면 주소로 정렬하면 보기 쉬워집니다.

그림의 회색 부분은 0x76d38500의 실제 주소에 로드된 LoadLibraryA 함수를 강조 표시합니다.
그럼 IAT 주소 좀 알려주세요.IMPORT_BY_네임으로 바꿔드릴게요.
여기서 주의해야 할 건 IMAGE입니다.IMPORT_BY_NAME는 다음과 같은 형식의 구조체이기 때문에 문자열의 시작 주소를 직접 가리키면 순조롭게 진행될 수 없습니다.
typedef struct {
    WORD Hint;
    BYTE Name[1];
} IMAGE_IMPORT_BY_NAME;
2바이트 이전의 주소인 WORD 형식의 사본이 필요합니다.
이번 예에서 다음은 빨간색으로 둘러싸인 부분은LoadLibraryA라는 문자열+2바이트이고 시작 주소는 0x93b0이다.

그것을 이 가격으로 개작하면 된다.(아래 그림의 녹색)

이 곡조로 전부 다시 쓰다.

나는 이렇게 하면 실행할 수 있다고 생각한다.
IAT의 수동 복구는 여기까지입니다.

끝말


이번엔 IAT 수동 재건 보도입니다.
upx를 예로 들면 다른 패키지들도 같은 일을 할 수 있을 것 같다(하지 않았다).페이커의 종류가 다르기 때문에 주로 unpack의 관례가 있기 때문에 EP에 도달하면 똑같을 것이다.
나도 한 지 얼마 안 돼서 잘못한 것도 있다고 생각해.이 경우 무자비하게 찔러주세요.
그리고 이 보도는 많이 생략되었다.특히 PE 파일 형식 주변의 경우 제대로 닿지 않고 바이트 수만 어지럽게 표시된다.
PE 파일의 형식은 상당히 복잡해서 한 문장으로 이해할 수 있는 것이 아니라 나도 잘 모르겠다.
IAT의 재구축은 사람의 손이 할 일이 아니기 때문에 특별한 일이 없다면 패키지 구성 요소는 도구에 의존해야 한다.

참고 문헌


암페어(수동 재구축 IAT)
UPX 브로셔 패키지 해제 2/3
UPX에서 IAT의 매뉴얼 재구성 [분석편]
IAT:가져오기 주소 테이블 정보
PEFormat.pdf
주소 테이블 가져오기 및 API 연결
PE 파일 구조 - 가져오기 주소표 - AST
PE(Portable Executable) 파일 형식의 2~가져오기 정보 및 가져오기 함수 열거
PE(Portable Executable) 파일 형식의 개요

좋은 웹페이지 즐겨찾기