---
title: 'TH04 مهندسی معکوس: الگوهای گلوله DOS-REA'
url: https://rea.tools/fa/showcase/th04/
---

[خانه](https://rea.tools/fa/) / [ویترین ها](https://rea.tools/fa/showcase/) / TH04

مطالعه موردی \* Touhou 4: داستان سرزمین لوتوس

# بازسازی TH04 الگوهای گلوله.

یک حلقه گلوله با یک محاسبه زاویه کوتاه شروع می شود. از REA برای بازرسی تابع dos اصلی استفاده کنید ، سپس دستورالعمل های آن را به C read قابل خواندن دنبال کنید.

PC-98 · 16 بیتی DOS · c++ و مونتاژ

[بازسازی TH04 را مشاهده کنید](https://github.com/N0zoM1z0/th04)

از دستورالعمل های اصلی تا منبع چک شده

1. 01 \* بازی اصلی

   **اصلی.EXE**

   فایل اجرایی PC-98 و کمک کننده زاویه گلوله آن.
2. 02 \* با REA بازرسی کنید

   **دستورالعمل ها + مرجع**

   کد dos بارگذاری شده را تأیید کنید و محاسبه زاویه را از فایل اجرایی بخوانید.
3. 03 \* خواندن C++

   **فضا → هدف → چرخش**

   هر عملیات را به بازسازی نگهداری شده وصل کنید.
4. 04 \* منبع را بررسی کنید

   **2,139 بایت تطبیق**

   چک های کامپایلر ضبط شده کد تولید گلوله ای را که شامل این کمک کننده است ، پوشش می دهد.

REA کد اصلی و شواهد تجزیه و تحلیل آن را باز می گرداند. پروژه TH04 منبع نگهداری شده و چک های کامپایلر را تامین می کند.

## چگونه یک حلقه به بازیکن هدف می گیرد

حمله ی الی درخواست یک حلقه ی هدفمند با شمارش اولیه ی 16 می کند. یک یاور جهت هر گلوله را محاسبه می کند. همان حلقه می تواند با یک جهت ثابت روبرو شود یا به سمت بازیکن بچرخد.

عامل برنامه نویسی شما

استفاده از REA برای پیدا کردن چگونه TH04 ایجاد یک حلقه از گلوله و هدف آن را در بازیکن. محاسبه را توضیح دهید و کد را نشان دهید.

یک مثال سریع ، با فایل اجرایی اصلی و پرداخت بازسازی در دسترس محلی.

TH04 یک چرخش کامل در جهت عقربه های ساعت را در 256 واحد زاویه ذخیره می کند. برای 16 گلوله ، هر شاخص 16 واحد اضافه می کند: `0, 16, 32, …, 240`. اضافه کردن جهت بازیکن این موقعیت ها را با هم می چرخاند.

![دو نمودار یک حلقه 16 گلوله ای حلقه ثابت از زاویه صفر شروع می شود. اضافه کردن یک جهت بازیکن 40 هر جهت را با همان مقدار چرخش می دهد ؛ اولین گلوله برجسته به سمت بازیکن اشاره می کند. هر دو فاصله 16 واحد زاویه ای یا 22.5 درجه دارند.](https://rea.tools/assets/localized/fa/figures/th04-bullet-ring.svg)

یک تصویر از ریاضیات زاویه بازیابی شده برای شمارش 16 ، جهت بازیکن 40 و چرخش قالب 0. [شکل باز](https://rea.tools/assets/localized/fa/figures/th04-bullet-ring.svg)

### قالب شلیک در منبع بازیابی شده

حمله حلقه ای الی \* منبع گزیده

```
bullet_template.angle = 0;
bullet_template.group = BG_RING_AIMED;
bullet_template.count = 16;
bullet_template_tune();
```

این خطوط الگوی را قبل از دشواری و تنظیم عملکرد انتخاب می کنند. [منبع حمله رو بخون](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/boss/elly_phase_ring16.cpp#L26).

## چه REA باز می گردد

ما بازرسی می کنیم `bullet_velocity_and_angle_set()`، تابعی که سرعت و زاویه هر گلوله را تعیین می کند. REA دستورالعمل ها ، کد شبه و مرجع خود را باز می گرداند. سه قسمت از این نتیجه الگوی را توضیح می دهد.

1. #### قبل از خواندن کد آن ، تصویر DOS را بررسی کنید

   نماینده → REA

   ```
   open_binary
   {"path": "MAIN.EXE"}

   inspect_native_load_image
   {}
   ```

   REA → عامل \* زمینه های انتخاب شده

   ```
   status: "verified"
   format: "dos-mz"
   load_segment: 4096
   header_bytes: 6144
   module_bytes: 150114
   ```

   چک کد بارگذاری شده و سوابق جابجایی را به فایل اجرایی ارائه شده متصل می کند. مسیر بالا برای نمایش کوتاه شده است.
2. #### ضرب و تقسیم حلقه را بخوانید

   نماینده → REA · `analyze_function`

   ```
   {"procedure": "0x2cfc8"}
   ```

   REA → عامل \* گزیده دستورالعمل

   ```
   0x2d0eb: MOV AX, SI
   0x2d0ed: SHL AX, 0x8
   0x2d0f0: MOV DL, byte ptr [0x53af]
   0x2d0f9: IDIV BX
   ```

   `SI` شاخص گلوله را نگه می دارد. تغییر آن را با 256 ضرب می کند ، سپس تقسیم از شمارش خوانده شده از `DS:53AF`. نام های منبع نگهداری شده که فیلد `bullet_template.count`. دنباله کامل در زیر ظاهر می شود.
3. #### پیدا کردن جایی که الگوی به سمت بازیکن می چرخد

   نتیجه عملکرد مشابه \* گزیده aim

   ```
   0x2d190: SUB AX, word ptr [0x53a6]
   0x2d198: SUB AX, word ptr [0x53a4]
   0x2d19d: CALLF 0x1000:1da8
   0x2d1a2: ADD word ptr [BP + -0x2], AX
   ```

   C نگهداری شده مربوطه++

   ```
   group_angle_offset += iatan2(
     player_pos.cur.y - bullet_template.origin.y,
     player_pos.cur.x - bullet_template.origin.x
   );
   ```

   عملگرهای دستورالعمل دو تفاوت مختصات و یک کمک کننده جهت را نشان می دهند. مقدار بازگشت آن به زاویه حلقه نسبی اضافه می شود. نام های منبع این آدرس ها را قابل خواندن می کنند ؛ REA به نماینده اجازه می دهد عملیات اصلی پشت آنها را بررسی کند.

## از مونتاژ به c قابل خواندن++

یک مرحله را برای مطابقت دستورالعمل های اصلی با محاسبه زاویه انتخاب کنید. این خلاصه مسیر حلقه هدف را دنبال می کند ؛ منبع کامل همچنین گسترش ، پشته و الگوهای تصادفی را مدیریت می کند.

REA \* دستورالعمل های اصلی 16 بیتی

```
0x2cfcf: MOV SI, word ptr [BP + 0x4]
0x2d0eb: MOV AX, SI
0x2d0ed: SHL AX, 0x8
0x2d0f0: MOV DL, byte ptr [0x53af]
0x2d0f4: MOV DH, 0x0
0x2d0f6: PUSH DX
0x2d0f7: CWD
0x2d0f8: POP BX
0x2d0f9: IDIV BX
0x2d0fb: MOV word ptr [BP + -0x2], AX
0x2d18d: MOV AX, [0x4650]
0x2d190: SUB AX, word ptr [0x53a6]
0x2d194: PUSH AX
0x2d195: MOV AX, [0x464e]
0x2d198: SUB AX, word ptr [0x53a4]
0x2d19c: PUSH AX
0x2d19d: CALLF 0x1000:1da8
0x2d1a2: ADD word ptr [BP + -0x2], AX
0x2d1b9: MOV AL, byte ptr [BP + -0x2]
0x2d1bc: ADD AL, byte ptr [0x53ad]
0x2d1c0: MOV [0xbcc8], AL
```

قابل خواندن c summary \* هدف-خلاصه حلقه

```
unsigned char aimed_ring_angle(
    int index, int count,
    int player_direction,
    unsigned char rotation)
{
    int angle = index;
    angle = (angle * 256) / count;
    angle += player_direction;
    angle += rotation;
    return (unsigned char)angle;
}
```

**01 \* شاخص گلوله را بخوانید.** استدلال پشته بارگذاری شده است `SI`. در یک حلقه 16 گلوله ، این شاخص عضو از 0 تا 15 اجرا می شود.

**02 \* جهت ها را در اطراف یک چرخش کامل قرار دهید.** `SHL AX,8` ضرب در 256 شمارش صفر است-به یک کلمه گسترش می یابد ، سپس `IDIV` محصول را با این تعداد تقسیم می کند. برای شمارش 16 ، هر شاخص 16 واحد زاویه را پیش می برد.

**03 \* جهت بازیکن را اضافه کنید.** دو تفریق مختصات بازیکن-منهای-منشأ را تشکیل می دهند. کمک کننده جهت زاویه ای را در `AX` اضافه کردن کل حلقه رو به سمت بازیکن می چرخونه

**04 \* چرخش الگوی را اضافه کنید.** `ADD AL,[0x53ad]` زاویه قالب را اضافه می کند. الگوی اولیه ایلی آن را به صفر می رساند ؛ الگوهای دیگر می توانند از همان کمک کننده با چرخش استفاده کنند.

**05 \* زاویه نهایی را در یک بایت نگه دارید.** فروشگاه می نویسد `AL` به میدان زاویه تخم ریزی ارزش ها بعد از 255 بسته بندی می شوند ، درست مثل بازیگران بدون بایت. منبع اطراف نیز این زاویه و سرعت را به سرعت تبدیل می کند.

مجمع شاخه حلقه هدف ، محاسبه هدف و فروشگاه نهایی را انتخاب می کند. C++ بالا یک خلاصه قابل خواندن است. چک های کامپایلر زیر برای منبع نگهداری شده در پروژه مرتبط اعمال می شود.

حلقه نگهداری شده و منبع هدف را بخوانید

حلقه ماکرو \* TH04 شاخه ، گزیده

```
angle_offset = (i * BULLET_ANGLE_FULL_TURN) / count;
if (i >= (count - 1)) {
    group_complete = true;
}
goto aim_or_no_aim;
```

زاویه و سرعت \* منبع گزیده

```
aim:
    group_angle_offset += iatan2(
        (player_pos.cur.y - bullet_template.origin.y),
        (player_pos.cur.x - bullet_template.origin.x)
    );

no_aim:
    vector2_near(
        bullet_template.velocity,
        (group_angle_offset + bullet_template.angle),
        speed
    );
    bullet_spawn_angle = (group_angle_offset + bullet_template.angle);
```

[ماکرو حلقه](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/add_impl.hpp#L4) · [منبع هدف و سرعت](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/add.cpp#L422) · [نمایش زاویه](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/types.hpp#L6)

## بررسی منبع نگهداری شده

چک های ضبط شده پروژه TH04 کد تولید گلوله ، از جمله این کمک کننده را با زنجیره ابزار توربو C 4 4.0 J خود جمع آوری می کند.

### 2,139 بایت تطبیق

کد تولید گلوله کامپایل شده با بخش 2139 بایت از فایل اجرایی اصلی مطابقت دارد.

### دو ساخت تمیز

دو ساخت جداگانه همان بایت های تطبیق یافته را تولید می کنند. هش های ورودی ضبط شده با منبع نگهداری شده که در اینجا نشان داده شده مطابقت دارند.

ثبت شده در 3 اکتبر 2026. [چک های کامپایلر را بخوانید](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/docs/reconstruction/product/TH04_SEMANTIC_BULLET_GENERATION_V1236.md#validation).

محدوده هویت و تجزیه و تحلیل هدف

|  |  |
| --- | --- |
| هدف اصلی | `MAIN.EXE`, 156,258 بایت, DOS MZ |
| ورود کمک کننده | `0x2cfc8` در REA ' s تصویر لود |
| فایل اصلی جبران | `0x1e7c8`، بازگشت توسط `address_to_file_offset` |
| بازرسی کد ثبت شده | REA 4.1.0 \* 7 اکتبر 2026 |

چک های کامپایلر بخش کامل کد bullet-add را شامل می شود ، از جمله این کمک کننده. آنها همچنین سهم نقشه و جابجایی همپوشانی آن را مقایسه می کنند.

REA تصویر بار dos استاتیک را در بخش بار تأیید کرد `0x1000`. آدرس های آن تصویر تجزیه و تحلیل را توصیف می کند. نتیجه تابع 503 بایت بدن را در دو محدوده در طول 517 بایت گزارش می کند ؛ دستورالعمل های انتخاب شده در بالا در آن محدوده های گزارش شده قرار دارند.

نام منبع و چک های کامپایلر از نقطه بازرسی TH04 می آیند `0d72e980`. مشاهدات بازسازی قبلی از اسکریپت های تجزیه و تحلیل پروژه استفاده می کردند ؛ این صفحه یک بازرسی REA تازه از همان هدف اصلی را اضافه می کند. هویت بازی عرضه شده توسط فهرست مخزن آن قرار گرفته است ، با منبع مستقل پاک و پاک هنوز باز است.

شکل محاسبه زاویه را نشان می دهد. کنترل های کامل بازی ، زمان بندی و رفتار سخت افزاری PC-98 دارای بررسی های زمان اجرا جداگانه در پروژه بازسازی هستند.

## بازسازی کامل TH04

این پروژه چهار محصول dos بازی را از Ctained و مونتاژ نگهداری می کند. فراتر از تولید گلوله ، منبع شامل مراحل ، کارفرمایان ، رندر ، ورودی ، منوها ، پایان ها و مدیریت امتیاز است.

[مخزن TH04 را کاوش کنید](https://github.com/N0zoM1z0/th04)

- [منبع تولید گلوله](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/src/main/bullet/add.cpp#L292)یار کامل ، انواع دیگر الگو و تنظیم قالب.
- [راهنمای ساخت و اجرای DOS](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/docs/DOS_BUILD.md)منبع را بسازید و آن را در جریان کار شبیه ساز PC-98 پروژه تست کنید.
- [وضعیت فعلی پروژه](https://github.com/N0zoM1z0/th04/blob/0d72e9801a5c14c10384efcbb6734ceccb74ee63/docs/RE_HANDOFF.md)تایید DOS و پورت x64 بومی جداگانه.
