반응형

Ghidra에서 (**(code **)(*XX + 0xYY))(ZZ) 형태의 명령어로 디컴파일 되는 경우가 있다.

이때, (**(code **)(*XX + 0xYY))는 함수를 가리키는 포인터, (ZZ)는 함수의 파라미터 부분인거 같다.

 

C++의 가상함수 테이블에서 이런 경우가 생기는거 같고, Visual Basic에서도 생기는거 같다.

함수의 위치가 정확히 정해진게 아니고 레지스터 값을 이용해 위치를 계산해야 하기 때문에 이렇게 되는거 같다.

 

※ 참고

Stack Overflow

Functions of the Visual Basic 6.0 Library

 

Music_Player.zip
9.52MB

 

 

Ghidra 분석

 

piVar3, local_a8은 모두 포인터이며 특히 여기선 (**(code **)(*piVar3 + 0x44)) 호출 후 local_a8에 값이 저장된다.

 

x64dbg 분석

Ghidra에서 분석한 포인터 local_a8은 [ebp-A4]이다.

0040455D에서 [ebp-A4]의 값을 eax로 옮기고 00404563에서 cmp eax, EA60 명령으로 60,000과 비교하고 있다.

(0xEA60 = 60,000)

 

 

 

정적 분석(Ghidra)으로는 (**(code **)(*piVar3 + 0x44))라는 함수의 위치를 파악하기 어려운거 같다. 동적 분석(x64dbg)으로 00404545 call dword ptr ds:[edx+44] 명령이 이동하는 곳을 따라가 보면 0x004055A0인것을 알 수 있고 함수로 인식되어 있다.

 

Ghidra에서도 2개의 포인터를 인수로 받는 FUN_004055a0라는 함수로 인식되어 있다.

 

  local_1c = 0;
  local_20 = 0;
  (**(code **)(*param_1 + 100))(param_1,2,&local_20);
  local_1c = local_20;
  (**(code **)(*param_1 + 8))(param_1);
  *param_2 = local_1c;

 

디스어셈블된 FUN_004055a0의 코드 중 하단부를 다시 살펴 보면 1~2 번째 줄에 의해 local_1c, local_20은 0으로 초기화 되고 3 번째 줄 함수 호출에서 파라미터로 넘어간 local_20에 어떤 값이 저장되어 4번째 줄에서 local_1c에 다시 저장된다. 그리고 마지막 줄 *param_2 = local_1c; 명령에 의해 제일 위 그림에서 설명했던 local_a8에 값이 저장된다.

(이전 함수에서 파라미터로 넘긴 local_a8이 지금 함수에서 param_2다)

 

2025.07.19 - [Reverse Engineering] - [x32dbg/x64dbg] Exception Handling and Call Stack Check 예외 처리 및 콜스택 확인

 

반응형
Posted by J-sean
: