- 55
- 유지보수 중인 C 함수
- 45,380
- 원본 코드와의 비교
- 33
- 컴파일된 바이트가 일치하는 함수
프로젝트 체크포인트: 2026년 10월 7일. 진행 기록 · 테스트 범위
지금까지의 프로젝트
복구된 코드는 보드와 리소스 처리, 벽돌 충돌, 애니메이션, 파티클, 보너스 생성을 다룹니다. 현재 빌드는 분석 유틸리티와 라이브러리를 제공합니다. 플레이 가능한 게임을 위해 공·패들의 물리, 파워업 처리, Windows 통합 작업이 계속되고 있습니다.
왼쪽/오른쪽 사운드 위치 계산 찾기
벽돌에 맞으면 가로 위치가 사운드 코드로 전달됩니다. 이 화면 좌표가 어떻게 좌우 패닝 값으로 바뀌는지 복구하는 조사입니다.
REA로 DX-Ball의 사운드 패닝 계산 방식을 찾아줘. 계산을 설명하고 코드도 보여줘.
로컬 실행 파일을 준비한 상태에서 쓰는 코딩 에이전트용 프롬프트입니다. 아래 조사에서 답변의 근거가 된 REA 질의와 증거를 볼 수 있습니다.
에이전트는 REA로 함수를 살펴보고, 벽돌 충돌 처리 함수가 이 함수를 어떻게 호출하는지 추적한 뒤 실행 파일의 상수를 읽었습니다. 이 결과로 입력과 계산 방법을 확인하고 아래의 C 함수를 작성했습니다.
0x406400의 첫 함수 분석 결과에는 FUN_00406400(void)을 선언하고 __ftol()를 호출하는 의사 코드가 포함되어 있었습니다. 명령어 보기에는 스택 입력과 부동 소수점 연산이 나타났습니다. 이 불일치는 에이전트가 조사를 계속할 구체적인 근거가 되었습니다.
첫 디컴파일 결과
longlong FUN_00406400(void)
{
longlong lVar1;
lVar1 = __ftol();
return lVar1;
}
출력에는 변환 함수 호출이 나타납니다. 아래의 명령어를 읽으면 그 호출에 전달되는 입력과 계산 과정을 알 수 있습니다.
REA로 답을 찾은 세 가지 질문
-
누락된 입력 복구
에이전트 → REA ·analyze_function{"procedure": "0x406400"}REA → 에이전트 · 명령어 발췌문0x406409: MOV EAX, dword ptr [EBP + 0x8] 0x40640c: MOV dword ptr [EBP + -0xc], EAX 0x40640f: FILD dword ptr [EBP + -0xc]함수 결과에는 의사 코드, 호출 함수와 함께 명령어가 포함됩니다. 여기서는
[EBP+8]이 디컴파일 결과에 빠진 정수 입력을 드러냅니다. -
호출 함수를 따라 입력 의미 확인
에이전트 → REA ·analyze_function{"procedure": "0x411f40"}REA → 에이전트 · 호출 함수 발췌0x411f5b: ADD EAX, 0x14 0x411f5e: PUSH EAX 0x411f5f: CALL 0x00406400REA는 첫 결과에서 이 호출 함수를 식별했습니다. 앞선 명령어는
tile_x에 30을 곱하고 20을 더해 벽돌의 화면 좌표20 + 30 × tile_x을 구합니다. -
메모리 주소 뒤에 있는 값 읽기
에이전트→ REA · 두read_bytes요청{"address": "0x420068", "length": 16} {"address": "0x4210a0", "length": 8}REA 바이트 분석 결과 · 배정밀도 부동소수점으로 해석000000000000f93f → 1.5625 0000000000407f40 → 500.0 000000000000f03f → 1.0반환된 바이트로 연산 상수 두 개와 초기 패닝 배율을 확인합니다. 이제 에이전트는 C 수식에 필요한 값을 모두 갖췄습니다.
REA 분석 결과에서 C 코드로
아래 다섯 단계를 선택해 보세요. 각 단계에 해당하는 원본 명령어와 이를 바탕으로 작성한 C 코드가 강조됩니다.
0x406409: MOV EAX, dword ptr [EBP + 0x8]
0x40640c: MOV dword ptr [EBP + -0xc], EAX
0x40640f: FILD dword ptr [EBP + -0xc]
0x406415: FMUL double ptr [0x00420068]
0x40641e: FSUB double ptr [0x00420070]
0x406427: FMUL double ptr [0x004210a0]
0x406430: CALL 0x0041678c
0x40643e: RET
DxBallInt dxball_screen_pan(DxBallInt x)
{
double pan;
pan = (double)x;
pan = pan * 1.5625;
pan = pan - 500.0;
pan = pan * dxball_pan_scale;
return (DxBallInt)pan;
}
01 · 입력을 읽습니다. REA의 함수 결과에 있는 명령어 뷰에서는 [EBP+8]를 읽고 FILD로 정수를 로드합니다. REA로 호출 함수를 추적하면 C 매개변수 x가 화면 좌표임을 확인할 수 있습니다.
02 · 1.5625를 곱합니다. FMUL 명령은 0x420068의 double 값을 읽습니다. REA의 read_bytes가 반환한 바이트를 해석하면 1.5625가 나오며, C 코드도 같은 상수를 사용합니다.
03 · 500.0을 뺍니다. FSUB 명령은 0x420070의 double 값을 읽습니다. REA의 바이트 결과를 해석하면 500.0가 나옵니다. 이 값을 빼면 계산의 중심이 화면 좌표 320로 이동합니다.
04 · 저장된 배율을 적용합니다. 두 번째 FMUL 명령은 0x4210a0의 값을 읽습니다. 이 전역 변수의 이름은 유지 관리 중인 소스에서 dxball_pan_scale입니다. REA로 바이트를 두 번째로 읽어 초기값이 1.0임을 확인합니다.
05 · 정수를 반환합니다. 0x406430의 호출은 __ftol로 이어지며, 이는 REA의 피호출 함수 결과에서 확인됩니다. C 코드는 결과를 DxBallInt로 형 변환합니다. 원본 x86 코드와의 비교로 반환값을 검사합니다.
어셈블리 발췌문은 입력, 연산, 반환 명령어를 골라 보여줍니다. 아래 전체 목록에는 중간 저장과 함수의 준비·정리 명령도 포함됩니다.
전체 어셈블리와 근거 자료
0x406400: PUSH EBP
0x406401: MOV EBP, ESP
0x406403: SUB ESP, 0xc
0x406406: PUSH EBX
0x406407: PUSH ESI
0x406408: PUSH EDI
0x406409: MOV EAX, dword ptr [EBP + 0x8]
0x40640c: MOV dword ptr [EBP + -0xc], EAX
0x40640f: FILD dword ptr [EBP + -0xc]
0x406412: FST double ptr [EBP + -0x8]
0x406415: FMUL double ptr [0x00420068]
0x40641b: FST double ptr [EBP + -0x8]
0x40641e: FSUB double ptr [0x00420070]
0x406424: FST double ptr [EBP + -0x8]
0x406427: FMUL double ptr [0x004210a0]
0x40642d: FST double ptr [EBP + -0x8]
0x406430: CALL 0x0041678c
0x406435: JMP 0x0040643a
0x40643a: POP EDI
0x40643b: POP ESI
0x40643c: POP EBX
0x40643d: LEAVE
0x40643e: RET
호출하는 함수가 제공하는 것
0x411f40의 벽돌 충돌 함수는 타일 좌표에 30을 곱하고 20을 더한 뒤, 호출 전에 스택에 넣습니다:
0x411f50: MOV EAX, dword ptr [EBP + 0x8]
0x411f53: ADD EAX, EAX
0x411f55: LEA EAX, [EAX + EAX*0x2]
0x411f58: LEA EAX, [EAX + EAX*0x4]
0x411f5b: ADD EAX, 0x14
0x411f5e: PUSH EAX
0x411f5f: CALL 0x00406400
0x411f64: ADD ESP, 0x4
데이터 읽기로 확인한 값
| 주소 | 값 | 용도 |
|---|---|---|
0x420068 |
1.5625 |
첫 번째 곱셈 |
0x420070 |
500.0 |
빼기 |
0x4210a0 |
1.0의 초깃값 |
저장된 패닝 배율 |
해시로 고정한 DX-Ball 1.07 대상을 REA 4.1.0으로 분석한 기록입니다. 연결된 조사 메모에 Evidence ID가 보존돼 있습니다.
복구한 함수 검증
복구한 함수는 두 검사를 통과합니다. 반환값이 원본과 일치하고, 컴파일된 바이트도 실행 파일과 일치합니다.
동작 검증 사례 3,205개
테스트는 원래 x86 함수를 실행하고 그 반환값을 유지보수 중인 C 코드의 반환값과 비교합니다. 팬 스케일 0, 0.5, 1, 20, −1의 다섯 가지 값에 대해 0부터 640까지의 모든 정수 위치를 검사합니다.
바이트 63개 일치
C 함수는 버전이 고정된 VC4.0 도구 모음으로 컴파일됩니다. 검토된 재배치를 적용하고 참조된 상수를 확인하면 컴파일러 재현 결과가 함수 전체와 일치합니다.
배율이 1일 때 복구한 계산은 왼쪽 끝에서 −500, 중앙에서 0, 오른쪽 끝에서 500을 반환합니다. 다음 오디오 작업은 이 값을 게임의 사운드 백엔드와 연결하는 것입니다.
조사 이어가기
파티클 갱신, 폭발 대기열, 보너스 생성에도 같은 방법을 사용합니다. 관련 함수를 살펴 상태와 의존 관계를 복구한 뒤 구현을 원본과 비교합니다.
사운드 패닝 함수를 직접 분석하려면 DX-Ball 프로젝트의 설정 지침을 따르고 일치하는 원본 파일을 준비하세요. 그런 다음 실행하세요:
scripts/rea function original/DXBALL.EXE 0x00406400 \
--snapshot .analysis/rea/dxball.snapshot.json --json
- DX-Ball 저장소현재 소스, 진행 상황, 로컬 설정.
- REA 분석 절차계산 과정을 따라가고, 직접 고른 바이너리에도 같은 방법을 적용하세요.
- 파티클과 보너스 생성상태, 큐, 픽셀 쓰기를 다루는 더 큰 조사입니다.