반응형

Anti-Disassembly 로 많이 사용되는 EB FF 코드에 대해 간단히 살펴보자.

 

EB는 1바이트(-128 ~ +127) 이내 거리로 이동하는 Jump Short 명령이다.

위 그림에서 0x0040123F EB 03은 다음 명령어 주소(0x00401241)를 기준으로 03바이트 이동한 0x00401244로 이동한다.

 

EB 03을 EB FF로 바꿔보자.

FF는 -1을 의미하기 때문에 다음 명령어 주소 0x00401241에서 -1만큼 이동한 0x00401240으로 이동하라는 뜻이다. 그래서 화살표가 다른 곳을 가리키지 않고 명령어 자신을 가리키고 있다. (잘린것 처럼 보인다)

 

엔터키를 눌러 Jump 명령을 실행해 보면 EB FF 명령 중간인 FF의 위치, 0x00401240으로 이동한다.

 

※ 참고

ANTI-DISASSEMBLY TECHNIQUES

Assembly “wrapping”: a technique for anti-disassembly

 

반응형
Posted by J-sean
:
반응형

실행되는 명령들의 log를 남겨보자.

 

Trace into...나 Trace over...를 선택한다.

 

Log Text에 아래와 같은 포맷을 지정한다.

0x{p:cip} {i:cip}

Maximum trace count를 적당히 지정한다.

로그 파일의 이름이나 위치를 바꾸고 싶다면 Log File... 버튼을 클릭한다. (특별히 바꾸고 싶지 않아도 지정은 해줘야 한다. 그렇지 않으면 로그 파일이 생성되지 않는다)

 

지정된 숫자 만큼 명령이 실행되고 로그 파일이 생성된다.

 

※ 참고

Values

Expressions

String Formatting

 

반응형
Posted by J-sean
:
반응형

x64dbg에서 디버깅 중 Pause 명령이 실행되지 않는 경우가 있다.

 

F12 키를 누르면 에러가 발생한다.

 

Threads 탭을 확인해 보자.

 

현재 실행되고 있는 Thread가 Main이 아닌, 7번 14328이기 때문이다. 나머지 Thread는 Suspended 되어 있다.

 

Main 스레드에서 우클릭 - Switch Thread를 선택한다.

 

Pause는 Main 스레드에서만 사용할 수 있다. Main 스레드로 바꾸면 Pause를 사용할 수 있다.

 

반응형
Posted by J-sean
:
반응형

x64dbg와 Claude Desktop, Gemini CLI를 사용해 보자.

 

x64dbgMCP를 다운로드한다.

 

MCPx64dbg.dp64와 x64dbg.py를 x64dbg 플러그인 폴더에 복사한다.

 

x64dbg를 실행하고 Log 윈도우를 확인하면 MCPx64dbg 플러그인이 로드되어 있다.

 

{
  "mcpServers": {
      "ghidra": {
        "command": "python",
        "args": [
          "D:\\ProgramFiles\\ghidra\\bridge_mcp_ghidra.py",
          "--ghidra-server",
          "http://127.0.0.1:8080/"
        ]
      },
      "x64dbg": {
        "command": "Python",
        "args": [
          "D:\\Program Files\\x64dbg\\release\\x64\\plugins\\x64dbg.py"
        ]
      }
  }
}

 

claude_desktop_config.json 파일에 x64dbg 내용을 추가한다.

 

클로드를 실행하면 x64dbg 로컬 MCP 서버가 실행되어 있다.

 

x64dbg에서 디버깅을 시작한다.

 

 

Claude에서 질문을 하면 답을 찾아간다.

 

근거 있는 답변을 제시한다.

 

질문 내용에 따라 Ghidra와 x64dbg를 구분하지 못하는 경우가 있다.

 

 

{
  "selectedAuthType": "oauth-personal",
  "theme": "Default",
  "mcpServers": {
      "ghidra-mcp": {
        "command": "python",
        "args": [
          "D:\\ProgramFiles\\ghidra\\bridge_mcp_ghidra.py",
          "--ghidra-server",
          "http://127.0.0.1:8080/"
        ]
      },
      "x64dbg": {
        "command": "Python",
        "args": [
          "D:\\Program Files\\x64dbg\\release\\x64\\plugins\\x64dbg.py"
        ]
      }
  }
}

 

Gemini CLI 설정 파일 settings.json에 x64dbg MCP Server 내용을 위와 같이 추가한다.

 

Gemini를 실행하면 2개의 MCP Server(Ghidra, x64dbg)가 실행되고 있다고 표시된다.

 

실행되고 있는 x64dbg에 대한 질문을 할 수 있다.

 

질문 내용에 따라 Ghidra와 x64dbg를 구분하지 못하는 경우가 있다.

 

반응형
Posted by J-sean
:
반응형

GhidraMCP와 클로드, 제미나이 CLI를 사용해 보자.

 

Claude에 가입하고 Claude Desktop을 설치한다.

GhidraMCP를 다운로드하고 압축을 푼다. 압축을 풀면 아래와 같은 2개의 파일이 나온다.

 - GhidraMCP-(version).zip

 - bridge_mcp_ghidra.py

이 중 bridge_mcp_ghidra.py 파일은 Ghidra 설치 폴더에 복사한다. (예: D:\ProgramFiles\ghidra)

 

File - Install Extensions 를 선택한다.

 

오른쪽 상단의 + 버튼을 클릭하고 GhidraMCP-(version).zip을 선택한 후 체크 표시가 되면 OK를 클릭한다. 그리고 Ghidra를 다시 실행한다.

 

CodeBrowser에서 File - Configure를 선택한다.

 

Developer - Configure - GhidraMCPPlugin이 체크되어 있는지 확인한다.

 

 

Claude - 파일 - 설정을 클릭한다.

 

개발자 - 구성 편집을 클릭한다.

 

Claude 폴더 - claude_desktop_config.json 파일을 아래 코드와 같이 편집한다.

 

{
  "mcpServers": {
    "ghidra": {
      "command": "python",
      "args": [
        "D:\\ProgramFiles\\ghidra\\bridge_mcp_ghidra.py",
        "--ghidra-server",
        "http://127.0.0.1:8080/"
      ]
    }
  }
}

 

위에서 Ghidra 설치 폴더로 복사해 둔 bridge_mcp_ghidra.py 의 경로 D:\ProgramFiles\ghidra 표현 시 역슬래시 2개를 사용하는것에 주의한다.

 

 

Claude - 파일 - 종료를 선택해 종료하고 Claude를 다시 실행한다. 오른쪽 상단 X 버튼을 클릭해 종료하면 진짜 종료되지 않는다.

 

Claude를 다시 실행해 보면 로컬 MCP 서버가 실행되고 있다.

 

다시 첫 화면으로 돌아와 검색 및 도구 버튼을 클릭하면 ghidra가 활성화 되어 있다.

 

Ghidra로 원하는 프로그램을 분석하다가 FUN_00401130 함수의 역할이 궁금해졌다고 가정하자.

 

 

원하는 함수를 분석해 결과를 알려준다.

 

변수 이름을 알기쉽게 바꿔 달라고 요청해 본다.

 

변수 이름 뿐만 아니라 함수 이름까지 적당히 바꿔서 결과를 출력해 준다.

 

함수 위치에서 대충 질문해도 알아서 잘 답해준다.

 

 

Gemini-CLI를 설치한다.

 

Gemini CLI의 세팅 파일은 settings.json이다.

 

{
  "selectedAuthType": "oauth-personal",
  "theme": "Default",
  "mcpServers": {
    "ghidra-mcp": {
      "command": "python",
      "args": [
        "D:\\ProgramFiles\\ghidra\\bridge_mcp_ghidra.py",
        "--ghidra-server",
        "http://127.0.0.1:8080/"
      ]
    }
  }
}

 

settings.json을 위와 같이 작성한다.

 

Gemini CLI를 실행하면 위와 같이 1개의 MCP server가 사용되고 있음이 표시된다.

 

Ctrl+t 키를 누르면 사용 가능한 툴이 표시된다.

 

Ghidra에서 분석을 진행하다 궁금한게 있다면 질문하고 답변을 받을 수 있다.

 

반응형
Posted by J-sean
:
반응형

실행 파일에서 원하는 리소스를 찾아보자.

 

ImagePrc.zip
0.12MB

 

 

 

ImagePrc.exe 를 x32dbg - xAnalyzer로 분석하면 위와 같이 FindResourceA 함수에서 두 번째 인수인 리소스 이름으로 65를 사용한 것을 확인할 수 있다. FindResourceA 함수의 두 번째 인수는 포인터가 아닐 경우 MAKEINTRESOURCE(ID) 이다.

 

 

PE를 분석하면 Resource ID가 65인 데이터를 찾을 수 있다.

 

반응형
Posted by J-sean
:
반응형

간단한 비주얼 베이직 프로그램으로 VB Decompiler 사용법을 익혀보자.

 

Music_Player.zip
9.52MB

 

 

Music_Player 실행 화면.

 

VB Decompiler로 Music_Player를 로드하면 간단한 프로그램 정보를 확인할 수 있다.

 

Forms - FrmMain에서 프로그램에 쓰인 여러가지 컨트롤 정보를 확인 할 수 있다.

예를 들어 STOP 버튼은 Caption으로 '■' 문자를 사용하고 (1680, 1560, 615, 495)에 위치하며 이벤트 처리 함수는 CMD_STOP이다.

 

CMD_STOP_Click() 의 디컴파일 내용을 확인 할 수 있다.

 

 

디스어셈블 내용도 확인 할 수 있다.

 

x32dbg에서 CMD_STOP()의 주소 00403EE0 로 이동해도 같은 내용을 확인할 수 있다.

 

ClsMCI에서 그 외 정의된 처리 함수들을 확인할 수 있다.

 

반응형
Posted by J-sean
:
반응형

Ghidra 사용 방법에 관해 간단히 정리해 보자.

 

downloader(암호는pass).zip
0.09MB

 

 

Image Optional Header 내용을 살펴보면 Address of Entry Point가 00401437이고 Base of Code가 00401000이라는 것을 알 수 있다.

 

Entry Point를 쉽게 찾을 수 있다.

 

Base of Code(00401000)도 쉽게 찾을 수 있다.

 

C 프로그램의 경우 Base of Code가 main()인 경우가 많다.

 

 

 

Base of Code에서 XREF[]로 표시되는 상호 참조(Cross Reference)를 조금 더 자세히 살펴보자.

XREF[XX]에서 [XX]는 상호 참조 수를 의미한다.

XREF[XX] 다음에 나오는 주소는 아래와 같은 의미를 갖는다.

 

■ Stack[-0x8]:4 local_8 XREF[6]: 00401009 => 4바이트의 local_8 변수가 00401009에서 사용된다. (그리고 5개 더 있다)

■ Stack[-0xc]:4 local_c XREF[1]: 00401010 => 4바이트의 local_c 변수가 00401010에서 사용된다.

■ Stack[-0x1c]... local_1c XREF[1]:00401068 => 1바이트의 local_1c 변수가 00401068에서 사용된다.

local_1c 부분에 마우스를 올리면 undefined Byte, Length: 1 이라고 표시되는데, 위 변수와의 차를 계산해 보면(0x1c-0xc) 실제로는 1바이트가 아닌 16(0x10) 바이트인 것을 알 수 있고 기본 자료형이 아닌 것을 알 수 있다.

■ Stack[-0x60]... local_60 XREF[2]:0040105e => 1바이트의 local_60 변수가 0040105e에서 사용된다. (그리고 1개 더 있다)

마찬가지로 위 변수와의 차를 계산해 보면(0x60-0x1c) 68(0x44) 바이트의 자료형이다.

■ Stack[-0x164]... local_164 XREF[3]:00401068 => 1바이트의 local_164 변수가 00401031에서 사용된다. (그리고 2개 더 있다)

마찬가지로 위 변수와의 차를 계산해 보면(0x164-0x60) 260(0x104)바이트의 자료형이다.

 

모두 -0xXX의 주소값을 갖는데, EBP-0xXX를 의미하며 함수의 지역변수를 의미하는거 같다.

 

 

Base of Code를 디컴파일한 내용을 다시 살펴보자.

local_1clocal164CreateProcessA()에서 사용되고 local_164는 문자열의 포인터, local_1c는 PROCESS_INFORMATION 구조체 (16바이트)인 것을 알 수 있다.

local_60GetStartupInfoA()에서 사용되고 STARTUPINFO 구조체(68바이트)인 것을 알 수 있다.

 

※ 크기는 모두 32비트 기준이다.

 

구조체에서 우클릭 - Edit Data Type을 선택해 보자.

 

구조체의 구성 정보를 모두 확인 할 수 있다.

 

 

 

그리고 마지막 부분에 Base of Code 함수인 FUN_00401000에 대한 상호 참조가 3개 있다.

이것은 0040011c, 004001f4, 그리고 __scrt_common_main_seh 함수의 004013ae 위치에서 FUN_00401000 함수가 호출되거나 사용된다는 것을 의미한다.

 

Listing 윈도우에서 툴바의 Edit the Listing fields 버튼을 클릭하면 여러가지 상황에서의 필드를 조정하거나 수정할 수 있다. 위 그림의 경우 Instruction/Data의 필드를 표시하고 있다. 마우스 오른쪽 버튼을 클릭하면 다른 필드를 추가하거나 삭제 할 수 있다.

 

리버스 엔지니어링 기드라 실전 가이드 p.142 오타 수정:

FUN_004010a0 함수의 제2인수(param_2)는 구조체의 세 번째 멤버 변수가 지정되었습니다. 주소 0x00418000을 선두로 하는 구조체의 경우 세 번째 멤버 변수인 0x00418008에 0x1a가 FUN_004010a0 함수의 제2인수가 됩니다.

 

Set Equate 명령은 1Ah 값 위에서 우클릭해야 표시된다.

 

※ SHGetSpecialFolderPath()에서 세 번째 인수에 0x1a가 들어갔을때의 의미:

CSIDL_APPDATA = 0x1A(26)
The file system directory that serves as a common repository for application-specific data.

Application Data(파일 시스템 디렉토리)

 

리버스 엔지니어링 기드라 실전 가이드 p.145 참고:

FUN_004010a0() - FUN_00401140() - FUN_00401180() - FUN_004011a0() 까지 들어가면 vsprintfg() 호출 명령이 있다.

 

리버스 엔지니어링 기드라 실전 가이드 p.147 오타 수정:

download_file 함수의 FUN_004010a0 함수 호출원을 디스어셈블한 결과를 Listing 창에서 확인해 보겠습니다. FUN_004010a0 함수 호출 이전에는 함수 선두에 있는 EBP 대피 처리를 제외하고 3개의 PUSH 명령이 있습니다. 주소 0x004010e8에서 PUSH되는 값은 디컴파일 결과에는 반영되어 있지 않았습니다.

 

FUN_004010a0()에 세 번째 인수(void *)는 위와 같이 추가한다.

 

리버스 엔지니어링 기드라 실전 가이드 p.148 참고:

구조체의 이름과 멤버 변수명을 바꿔주면 그 구조체가 사용된 함수들에서 함수의 파라미터로 전달된 구조체 이름이 자동으로 바뀌는 것처럼 설명되고 그림으로 표시되는데, 함수의 파라미터 이름은 모두 일일이 우클릭 - Rename Variable 명령으로 바꿔줘야 한다. 함수 이름, 구조체 멤버 변수 이름 등이 표시되는 부분은 수정시 자동으로 바뀐다.

 

또, 책을 따라 진행하고 나면 p.149의 예제 3-16 코드 부분에 나온 것보다는 보기 편하게 결과가 나온다.

예) download_file()의 파라미터 이름을 바꾸고 나면 3-16 코드에서 표시된 내부 코드 중 make_path(buf, conf->field_0x8, ...); 같은 부분에서 conf->field_0x8은 실제로는 conf->CSIDL로 보기 좋게 표시된다.

구조체 이름과 첫 번째 멤버 변수 이름 변경

 

리버스 엔지니어링 기드라 실전 가이드 p.151 참고:

자체 구조체 임포트에 필요한 download_conf.h 파일

download_conf.h
0.00MB

 

 

 

리버스 엔지니어링 기드라 실전 가이드 p.154 참고:

main 함수의 지역 변수들이 자동으로 바뀌어 있는것처럼 설명되지만 자동으로 바뀌지 않는다. 일일이 우클릭 - Rename Variable 명령으로 바꿔줘야 한다.

 

리버스 엔지니어링 기드라 실전 가이드 p.252 참고:

 

Window - Python은 없고 PyGhidra가 있다.

 

하지만 위와 같은 에러가 표시된다. Window - PyGhidra 위에 있는 Jython을 사용하자.

 

PyGhidra는 Ghidra API를 직접 사용할 수 있는 파이썬 라이브러리다.

 

Jython은 잘 된다.

 

 

※ 참고

Jython 윈도우에서 아무 명령어도 입력 하지 않은 상태에서 TAB키를 누르면 몇 칸을 건너 뛰지만 명령어를 입력하다 중간에 TAB 키를 누르면 관련 명령어가 표시된다.

 

 

※ 참고

 

Ghidra 설치 폴더 - support - pyghidraRun.bat를 실행하면 파이썬 가상 환경에 PyGhidra를 설치 할 수 있다.

 

그리고 위와 같은 위치에 pyghidra.exe, pyghidraw.exe 등이 설치된다.

 

 

그리고 환경 변수/시스템 변수로 GHIDRA_INSTALL_DIR = D:\ProgramFiles\ghidra를 입력하고 재부팅 후 실행하면 위와 같은 에러가 발생한다. 뭘 해야할지 모르겠다.

 

리버스 엔지니어링 기드라 실전 가이드 p.265 참고:

 

00100e00~00100e3f 까지 선택하고 custom_table.2944 라벨에서 우클릭을 해야 Data - Choose Data Type... 메뉴가 표시된다.

 

Data Type을 string으로 바꾸면 문자열로 표시된다.

 

 

리버스 엔지니어링 기드라 실전 가이드 p.267 참고:

디코딩할 Ghidra Script 작성

 

import string
import base64

default_b64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
def custom_b64decode(s, custom_table):
	s = s.translate(string.maketrans(custom_table, default_b64_table))
	return base64.b64decode(s)

b64_custom_table_addr = toAddr(0x100e00)
b64_custom_table_array = getBytes(b64_custom_table_addr, 64)
b64_custom_table_array

b64_custom_table = "".join([chr(b) for b in b64_custom_table_array])
b64_custom_table

enc = "4PpnRoanRomTze4SKPo+Zwd3IejS"
custom_b64decode(enc, b64_custom_table)

 

위 소스 중간쯤 b64_custom_table_array 명령을 실행하면 아래와 같은 결과가 나온다.
array('b', [98, 57, 86, 49, 50, 100, 80, 71, 116, 107, 55, 66, 75, 90, 85, 68, 47, 78, 74, 101, 88, 52, 118, 120, 106, 73, 99, 69, 82, 122, 72, 43, 112, 81, 103, 84, 53, 105, 119, 89, 65, 108, 77, 121, 67, 87, 79, 70, 102, 110, 114, 51, 83, 111, 113, 48, 54, 76, 56, 104, 97, 109, 115, 117])

 

이 결과는 0x100e00 주소에 있는 64바이트 문자열 b9V12dPGtk7BKZUD/NJeX4vxjIcERzH+pQgT5iwYAlMyCWOFfnr3Soq06L8hamsu의 첫 글자가 'b'라는 것과 각 문자의 10진수 ASCII CODE를 의미한다.

 

그 아래 명령...

b64_custom_table = "".join([chr(b) for b in b64_custom_table_array])

b64_custom_table

의 결과가...
'b9V12dPGtk7BKZUD/NJeX4vxjIcERzH+pQgT5iwYAlMyCWOFfnr3Soq06L8hamsu'

인 것을 통해서도 알 수 있다.

 

리버스 엔지니어링 기드라 실전 가이드 p.279 참고:

 

def list_xrefs_call_functions(func_name):
	manager = currentProgram.getFunctionManager()
	for func in manager.getFunctions(True):
		if func.getName() in func:
			for xref in getReferencesTo(func.getEntryPoint()):
				if xref.getReferenceType().toString() == 'UNCONDITIONAL_CALL':
					print('{} is called at {}'.format(func.getName(), xref, getFromAddress()))
					
dangerous_func_names = ['getpw', 'gets', 'sprintf', 'strcat', 'strcpy', 'vsprintf']
list_xrefs_call_functions(dangerous_func_names)

 

위 함수 전체를 그대로 갖다 붙여넣기 하면 안된다. 한 줄씩 복사해서 붙여 넣어야 한다.

 

Jython에서 실행하면 위와 같은 에러가 발생한다. FunctionDB 객체가 반복 가능하지 않다는데 어떻게 해야 할까?

 

 

리버스 엔지니어링 기드라 실전 가이드 p.285 참고:

 

golang_renamer.py
0.00MB

Ghidra Ninja의 golang_renamer

 

Script Manager - Manage Script Directories 클릭

 

Display file chooser to add bundles to list 버튼 클릭 하고 golang_renamer.py가 있는 폴더를 선택한다.

 

Ghidra Ninja 폴더에 Golang - golang_renamer.py가 추가된다.

 

리버스 엔지니어링 기드라 실전 가이드 p.301~303 참고:

 

winapi_32.gdt
3.01MB

 

libvcruntime.fidb
0.02MB

 

p.303에서 libvcruntime.fidb 파일을 임포트 하는 과정 중 File - Configure - Function ID 체크 과정은 필요 없다.

지금은 FunctionID를 체크하지 않아도 기본적으로 포함되기 때문에 바로 Tools - Function ID - Attach existing FidDb...를 클릭하면 된다.

 

리버스 엔지니어링 기드라 실전 가이드 p.304 참고:

 

find_apply_winmain.py는 예제소스에 포함되어 있다. 그런데 지금은 스크립트를 실행하면 에러가 난다.

 

 

리버스 엔지니어링 기드라 실전 가이드 p. 참고:

 

 

 

 

 

 

리버스 엔지니어링 기드라 실전 가이드 p. 참고:

 

 

 

리버스 엔지니어링 기드라 실전 가이드 p. 참고:

 

 

 

 

 

 

 

 리버스 엔지니어링 기드라 실전 가이드 p. 참고:

 

 

 

리버스 엔지니어링 기드라 실전 가이드 p. 참고:

 

 

 

반응형
Posted by J-sean
: