사례 연구·DX-Ball1.07

재건 DX-Ball
실행 파일에서.

목표는 1996년에 나온 Windows 게임을 유지보수 가능한 C 코드로 재구성하는 것입니다. REA는 에이전트가 원본 함수를 하나씩 분석하도록 돕습니다.

Windowsi386·C·REA

딕스볼EXE 기능 0x00406400 검사와REA. 명령어 로드 엑스,1.5625 곱하기,500.0 빼기,팬 스케일을 적용하고 정수를 반환합니다. 3,205 개의 경우에서 63 바이트와 일치하는 4.0 컴파일러 재생에 의해 원본 86 에 대해 독립적으로 검사됩니다.
하나의 기능,실행 파일에서 확인 된 C. REA 지침,호출자 및 데이터 읽기를 제공하고 재구성 프로젝트는 결과를 구현하고 테스트합니다. 열린 그림
55
유지 된 기능
45,380
원본 코드와 비교
33
컴파일된 바이트가 일치하는 함수

프로젝트 체크 포인트:2026 년 10 월 7 일. 진행 원장 · 테스트 범위

지금까지의 프로젝트

복구 된 코드는 보드 및 리소스 처리,벽돌 히트,애니메이션,입자 및 보너스 생산을 포함합니다. 현재 빌드는 검사 유틸리티와 분석 라이브러리를 제공합니다. 재생 가능한 게임에 대한 작업은 공 및 패들 물리학,파워 업 처리 및 Windows 통합.

왼쪽/오른쪽 사운드 위치 계산 찾기

벽돌이 부딪히면 수평 위치가 사운드 코드로 전달됩니다. 이 조사는 화면 좌표가 왼쪽/오른쪽 패닝 값이 되는 방법을 복구하는 데 필요했습니다.

코딩 에이전트

사용 REA 방법을 찾으려면 DX-Ball 사운드 패닝을 계산합니다. 계산을 설명하고 코드를 보여줍니다.

로컬 실행 파일을 사용할 수 있는 코딩 에이전트에 대한 예제 프롬프트입니다. 아래의 조사는 REA 답변 뒤에 쿼리 및 증거.

에이전트는 REA로 함수를 살펴보고, 벽돌 충돌 처리 함수가 이 함수를 어떻게 호출하는지 추적한 뒤 실행 파일의 상수를 읽었습니다. 이 결과로 입력과 계산 방법을 확인하고 아래의 C 함수를 작성했습니다.

에 대한 함수의 첫 번째 분석 결과 0x406400 포함 된 의사 코드 선언 FUN_00406400(void) 그리고 전화 __ftol(). 명령어 뷰는 스택 입력과 부동 소수점 연산을 보여주었습니다. 그 불일치로 인해 에이전트는 계속 조사해야 할 구체적인 이유를 얻었습니다.

첫 번째 디 컴파일러 뷰
REA결과·의사 발췌문
longlong FUN_00406400(void)
{
  longlong lVar1;

  lVar1 = __ftol();
  return lVar1;
}

출력은 전환 호출을 보여줍니다. 아래의 지침을 읽는 것은 입력 및 통화 공급 계산을 알 수있다.

세 가지 질문에 대한 답변 REA

  1. 누락된 입력 복구

    에이전트→ 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] 디컴파일러 보기에서 누락된 정수 입력을 노출합니다.

  2. 호출하는 함수를 따라 입력 내용을 파악합니다

    에이전트→ REA · analyze_function
    {"procedure": "0x411f40"}
    REA→agent·호출하는 함수 발췌문
    0x411f5b: ADD EAX, 0x14
    0x411f5e: PUSH EAX
    0x411f5f: CALL 0x00406400

    REA 첫 번째 결과에서 이 호출자를 식별했습니다. 이전 명령어 스케일 tile_x 30 으로;20 을 더하면 벽돌의 화면 좌표가 나옵니다, 20 + 30 × tile_x.

  3. 메모리 주소 뒤에 있는 값 읽기

    에이전트→ REA *두 read_bytes 요청
    {"address": "0x420068", "length": 16}
    {"address": "0x4210a0", "length": 8}
    REA결과의 바이트·디코딩으로 복식
    000000000000f93f → 1.5625
    0000000000407f40 → 500.0
    000000000000f03f → 1.0

    반환된 바이트는 두 개의 산술 상수와 초기 팬 스케일을 설정합니다. 이제 에이전트에 필요한 값이 있습니다.

에서REA's 결과 C

아래의 다섯 단계를 따르십시오. 각 선택 항목은 원래 지침과 그들이 알려준 다 라인을 강조 표시합니다.

원본 86*발췌
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 화면 좌표 의미 설정 다 매개 변수 x.

어셈블리 발췌는 입력,산술 및 반환 지침을 선택합니다. 아래의 전체 목록에는 중간 저장소와 기능 설정 및 정리가 포함되어 있습니다.

전체 조립 및 지원 증거
REA결과·0x406400–0x40643e
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

데이터 읽기 설정

REA바이트를 읽고,디코딩으로 little-endian 복식
주소 값 를 위해 사용하는
0x420068 1.5625 첫 번째 곱셈
0x420070 500.0 빼기
0x4210a0 1.0 처음에는 저장된 팬 스케일

녹음된 REA 4.1.0 해시 고정 DX-Ball 1.07 목표. 관련 조사 메모에는 증거 신분증이 남아 있습니다.

유지 소스 · 조사 노트 및 증거 참조

복구 된 기능 확인

복구된 함수는 두 가지 검사를 통과합니다.반환 값은 원본과 일치하고 컴파일된 바이트는 실행 파일과 일치합니다.

3,205 행동 사례

0,0.5,1,20 및 -1:그들은 다섯 팬 스케일에서 0 에서 640 까지의 모든 정수 위치를 커버합니다.

63 일치하는 바이트

이 함수는 고정 된 툴체인을 사용하여 컴파일됩니다. 컴파일러 재생은 검토된 재배치를 적용하고 참조된 상수를 확인한 후 전체 함수와 일치합니다.

1 의 척도에서 복구된 계산은 왼쪽 가장자리에서-500,중앙에서 0,오른쪽 가장자리에서 500 을 반환합니다. 오디오 작업의 다음 부분은 그 값을 게임의 사운드 백엔드와 통합하는 것입니다.

컴파일러 재생 세부 정보 읽기

조사 계속

입자 업데이트,폭발 대기열 및 보너스 생성에도 동일한 접근법이 사용되고 있습니다.관련 기능을 검사하고,상태와 의존성을 복구한 다음,구현을 원본과 비교합니다.

사운드 팬 기능을 직접 검사하려면 다음을 수행하십시오 DX-Ball 프로젝트의 설치 지침 및 일치하는 원래 대상을 제공합니다. 그런 다음 실행:

에DX-Ball체크아웃
scripts/rea function original/DXBALL.EXE 0x00406400 \
  --snapshot .analysis/rea/dxball.snapshot.json --json

상단