宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 3782|回复: 4

Delphi编写内存遍历工具

[复制链接]
  • TA的每日心情
    开心
    2024-12-9 18:45
  • 签到天数: 124 天

    [LV.7]常住居民III

    admin 发表于 2009-11-2 23:38:27 | 显示全部楼层 |阅读模式

    欢迎您注册加入!这里有您将更精采!

    您需要 登录 才可以下载或查看,没有账号?注册

    x

    1. unit Main;
    2. interface
    3. uses
    4.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    5.   Dialogs, StdCtrls, ExtCtrls, ComCtrls;
    6. type
    7.   PEdit = ^TEdit;
    8.   TFilterData = Record
    9.     m_Text: string;
    10.     m_Int: Integer;
    11.     m_UnSign: Cardinal;
    12.     m_Float: Single;
    13.     m_Double: Double;
    14.   End;
    15.   PFilterData = ^TFilterData;
    16.   
    17.   TfrmMain = class(TForm)
    18.     GroupBox1: TGroupBox;
    19.     cbProcess: TComboBox;
    20.     btReFresh: TButton;
    21.     Label1: TLabel;
    22.     edtBaseAddress: TEdit;
    23.     Label2: TLabel;
    24.     edtOffset1: TEdit;
    25.     Label3: TLabel;
    26.     edtOffset2: TEdit;
    27.     Label4: TLabel;
    28.     edtOffset3: TEdit;
    29.     Label5: TLabel;
    30.     edtOffset4: TEdit;
    31.     Label6: TLabel;
    32.     edtOffset5: TEdit;
    33.     Label7: TLabel;
    34.     edtOffset6: TEdit;
    35.     Label8: TLabel;
    36.     edtOffset7: TEdit;
    37.     Label9: TLabel;
    38.     edtOffset8: TEdit;
    39.     Label10: TLabel;
    40.     edtOffset9: TEdit;
    41.     Label11: TLabel;
    42.     edtOffset10: TEdit;
    43.     Label12: TLabel;
    44.     edtOffset11: TEdit;
    45.     Label13: TLabel;
    46.     edtOffset12: TEdit;
    47.     Panel1: TPanel;
    48.     GroupBox2: TGroupBox;
    49.     Label14: TLabel;
    50.     cbOffset3: TComboBox;
    51.     Label15: TLabel;
    52.     edtOffsetCount3: TEdit;
    53.     Label16: TLabel;
    54.     edtLoopCount3: TEdit;
    55.     GroupBox3: TGroupBox;
    56.     Label17: TLabel;
    57.     Label18: TLabel;
    58.     Label19: TLabel;
    59.     cbOffset2: TComboBox;
    60.     edtOffsetCount2: TEdit;
    61.     edtLoopCount2: TEdit;
    62.     GroupBox4: TGroupBox;
    63.     Label20: TLabel;
    64.     Label21: TLabel;
    65.     Label22: TLabel;
    66.     cbOffset1: TComboBox;
    67.     edtOffsetCount1: TEdit;
    68.     edtLoopCount1: TEdit;
    69.     Splitter1: TSplitter;
    70.     Panel2: TPanel;
    71.     Panel3: TPanel;
    72.     Splitter2: TSplitter;
    73.     lvResult: TListView;
    74.     Label23: TLabel;
    75.     Label24: TLabel;
    76.     lbRecordCount: TLabel;
    77.     Label26: TLabel;
    78.     lbSelectCount: TLabel;
    79.     Label28: TLabel;
    80.     Panel4: TPanel;
    81.     GroupBox6: TGroupBox;
    82.     rbText: TRadioButton;
    83.     rbInt: TRadioButton;
    84.     rbUnSign: TRadioButton;
    85.     rbFloat: TRadioButton;
    86.     rbDouble: TRadioButton;
    87.     GroupBox7: TGroupBox;
    88.     rbEqual: TRadioButton;
    89.     rbLarge: TRadioButton;
    90.     rbLess: TRadioButton;
    91.     rbUnequal: TRadioButton;
    92.     rbLargeOrEqual: TRadioButton;
    93.     rbLessOrEqual: TRadioButton;
    94.     rbBetween: TRadioButton;
    95.     lbFitler: TLabel;
    96.     edtFilter: TEdit;
    97.     lbLargeOrEqual: TLabel;
    98.     edtSmall: TEdit;
    99.     lbLessOrEqual: TLabel;
    100.     edtLarge: TEdit;
    101.     cbFilterInProcess: TCheckBox;
    102.     btFilterInResult: TButton;
    103.     btSave: TButton;
    104.     btStart: TButton;
    105.     btSelect: TButton;
    106.     btSaveToFile: TButton;
    107.     btClear: TButton;
    108.     chkFloatToInt: TCheckBox;
    109.     chkOffset1: TCheckBox;
    110.     chkOffset2: TCheckBox;
    111.     chkOffset3: TCheckBox;
    112.     chkTextMatch: TCheckBox;
    113.     procedure FormCreate(Sender: TObject);
    114.     procedure btReFreshClick(Sender: TObject);
    115.     procedure rbEqualClick(Sender: TObject);
    116.     procedure chkOffset1Click(Sender: TObject);
    117.     procedure chkOffset2Click(Sender: TObject);
    118.     procedure chkOffset3Click(Sender: TObject);
    119.     procedure btClearClick(Sender: TObject);
    120.     procedure btStartClick(Sender: TObject);
    121.     procedure cbProcessChange(Sender: TObject);
    122.     procedure lvResultClick(Sender: TObject);
    123.     procedure lvResultResize(Sender: TObject);
    124.     procedure btFilterInResultClick(Sender: TObject);
    125.     procedure rbTextClick(Sender: TObject);
    126.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
    127.     procedure btSaveClick(Sender: TObject);
    128.     procedure btSaveToFileClick(Sender: TObject);
    129.     procedure btSelectClick(Sender: TObject);
    130.   private
    131.     { Private declarations }
    132.     aryEdit: array[0..11] of PEdit;
    133.     ProcessHandel: THandle;
    134.     FResultCount: Cardinal;
    135.     FSelCount: Cardinal;
    136.     procedure SetResultCount(const Value: Cardinal);
    137.     procedure SetSelCount(const Value: Cardinal);
    138.     procedure SetSingleFilter(bSingle: Boolean);
    139.     procedure rbClick;
    140.     procedure rbTypeClick;
    141.     procedure ClearListView;
    142.     property ResultCount: Cardinal read FResultCount write SetResultCount;
    143.     property SelCount: Cardinal read FSelCount write SetSelCount;
    144.   public
    145.     { Public declarations }
    146.     procedure GetProcessInf;
    147.     procedure ReadMemData(P: Pointer; pData: PFilterData);
    148.     procedure ReadToListView(P: Pointer; Offset1,Offset2,Offset3: Cardinal);
    149.     procedure AddListItem(pData: PFilterData; Offset1,Offset2,Offset3: Cardinal);
    150.     procedure SaveSetting;
    151.     procedure ReadSetting;
    152.     function DebugPrivilege(bEnable: Boolean): Boolean;
    153.     function GetSelProcessHandel: THandle;
    154.     function DataFilter(pData: PFilterData): Boolean;
    155.     function StrToFloatEx(str: string): Extended;
    156.     function FloatToStrEx(flt: Extended): string;
    157.     function HexToCardinal(hex: string): Cardinal;
    158.     function IsFloat(f: Extended): Boolean;
    159.     function TruncEx(r: Real): Int64;
    160.     function ReadPointer(pAddress: Pointer): Pointer;
    161.     function ReadCardinal(pAddress: Pointer): Cardinal;
    162.     function ReadInteger(pAddress: Pointer): Integer;
    163.     function ReadSingle(pAddress: Pointer): Single;
    164.     function ReadDouble(pAddress: Pointer): Double;
    165.     function ReadUnicode(pAddress: Pointer): string;
    166.   end;
    167.   
    168. var
    169.   frmMain: TfrmMain;
    170. implementation
    171. uses Tlhelp32, psapi, IniFiles;
    172. {$R *.dfm}
    173. { TfrmMain }
    174. function TfrmMain.FloatToStrEx(flt: Extended): string;
    175. begin
    176.     try
    177.         Result := FloatToStr(flt);
    178.     except
    179.         Result := '0.0';
    180.     end;
    181. end;
    182. procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
    183. begin
    184.     ClearListView;
    185. end;
    186. procedure TfrmMain.FormCreate(Sender: TObject);
    187. begin
    188.     DebugPrivilege(True);
    189.     GetProcessInf;
    190.     SetSingleFilter(True);
    191.     aryEdit[0] := @edtOffset1;
    192.     aryEdit[1] := @edtOffset2;
    193.     aryEdit[2] := @edtOffset3;
    194.     aryEdit[3] := @edtOffset4;
    195.     aryEdit[4] := @edtOffset5;
    196.     aryEdit[5] := @edtOffset6;
    197.     aryEdit[6] := @edtOffset7;
    198.     aryEdit[7] := @edtOffset8;
    199.     aryEdit[8] := @edtOffset9;
    200.     aryEdit[9] := @edtOffset10;
    201.     aryEdit[10] := @edtOffset11;
    202.     aryEdit[11] := @edtOffset12;
    203.     ReadSetting;
    204. end;
    205. procedure TfrmMain.GetProcessInf;
    206. var
    207.   lppe: TProcessEntry32;
    208.   found : boolean;
    209.   Hand : THandle;
    210.   ProcessId:DWORD;
    211.   ProcessName:string;
    212. begin
    213.     cbProcess.Clear;
    214.     Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
    215.     lppe.dwSize := SizeOf(TProcessEntry32);
    216.     found := Process32First(Hand,lppe);
    217.     while found do
    218.     begin
    219.         ProcessName := StrPas(lppe.szExeFile);
    220.         if lppe.th32ProcessID>0 then
    221.         begin
    222.             ProcessId := lppe.th32ProcessID;
    223.             cbProcess.Items.AddObject(ProcessName,TObject(ProcessId));
    224.         end;
    225.         found := Process32Next(Hand,lppe);
    226.     end;
    227. end;
    228. function TfrmMain.GetSelProcessHandel: THandle;
    229. var
    230.     ProcessId: DWORD;
    231. begin
    232.     Result := 0;
    233.     if cbProcess.ItemIndex < 0 then exit;
    234.     ProcessId := DWORD(cbProcess.Items.Objects[cbProcess.ItemIndex]);
    235.     Result := OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
    236. end;
    237. procedure TfrmMain.rbClick;
    238. begin
    239.     if rbBetween.Checked then
    240.         SetSingleFilter(False)
    241.     else
    242.         SetSingleFilter(True);
    243. end;
    244. procedure TfrmMain.rbEqualClick(Sender: TObject);
    245. begin
    246.     rbClick;
    247. end;
    248. procedure TfrmMain.rbTextClick(Sender: TObject);
    249. begin
    250.     rbTypeClick;
    251. end;
    252. procedure TfrmMain.rbTypeClick;
    253. begin
    254.     if rbText.Checked then
    255.     begin
    256.         rbLarge.Enabled := False;
    257.         rbLess.Enabled := False;
    258.         rbUnequal.Enabled := False;
    259.         rbLargeOrEqual.Enabled := False;
    260.         rbLessOrEqual.Enabled := False;
    261.         rbBetween.Enabled := False;
    262.         rbEqual.Checked := True;
    263.     end else
    264.     begin
    265.         rbLarge.Enabled := True;
    266.         rbLess.Enabled := True;
    267.         rbUnequal.Enabled := True;
    268.         rbLargeOrEqual.Enabled := True;
    269.         rbLessOrEqual.Enabled := True;
    270.         rbBetween.Enabled := True;
    271.     end;
    272. end;
    273. function TfrmMain.ReadCardinal(pAddress: Pointer): Cardinal;
    274. var
    275.   tmp: Cardinal;
    276.   ReadCount: Cardinal;
    277. begin
    278.   Result := 0;
    279.   if ProcessHandel = 0 then exit;
    280.   if pAddress = nil then exit;
    281.   ReadProcessMemory(ProcessHandel, pAddress, @tmp, SizeOf(tmp), ReadCount);
    282.   Result := tmp;
    283. end;
    284. function TfrmMain.ReadDouble(pAddress: Pointer): Double;
    285. var
    286.   tmp: Double;
    287.   ReadCount: Cardinal;
    288. begin
    289.   Result := 0;
    290.   if ProcessHandel = 0 then exit;
    291.   if pAddress = nil then exit;
    292.   ReadProcessMemory(ProcessHandel, pAddress, @tmp, SizeOf(tmp), ReadCount);
    293.   Result := tmp;
    294. end;
    295. function TfrmMain.ReadInteger(pAddress: Pointer): Integer;
    296. var
    297.   tmp: Integer;
    298.   ReadCount: Cardinal;
    299. begin
    300.   Result := 0;
    301.   if ProcessHandel = 0 then exit;
    302.   if pAddress = nil then exit;
    303.   ReadProcessMemory(ProcessHandel, pAddress, @tmp, SizeOf(tmp), ReadCount);
    304.   Result := tmp;
    305. end;
    306. procedure TfrmMain.ReadMemData(P: Pointer; pData: PFilterData);
    307. begin
    308.     pData.m_Text := ReadUnicode(P);
    309.     pData.m_Int := ReadInteger(P);
    310.     pData.m_UnSign := ReadCardinal(P);
    311.     try
    312.         pData.m_Float := ReadSingle(P);
    313.     except
    314.         pData.m_Float := 0.0;
    315.     end;
    316.     try
    317.         pData.m_Double := ReadDouble(P);
    318.     except
    319.         pData.m_Double := 0.0;
    320.     end;
    321. end;
    322. function TfrmMain.ReadPointer(pAddress: Pointer): Pointer;
    323. var
    324.   tmp: Cardinal;
    325.   ReadCount: Cardinal;
    326. begin
    327.   Result := nil;
    328.   if ProcessHandel = 0 then exit;
    329.   if pAddress = nil then exit;
    330.   ReadProcessMemory(ProcessHandel, pAddress, @tmp, SizeOf(tmp), ReadCount);
    331.   Result := Pointer(tmp);
    332. end;
    333. procedure TfrmMain.ReadSetting;
    334. var
    335.     iniFile: TIniFile;
    336.     strPath: string;
    337. begin
    338.     strPath := GetCurrentDir+'\Readmem.ini';
    339.     iniFile := TIniFile.Create(strPath);
    340.     edtBaseAddress.Text := iniFile.ReadString('ReadMem','edtBaseAddress','');
    341.     edtOffset1.Text := iniFile.ReadString('ReadMem','edtOffset1','');
    342.     edtOffset2.Text := iniFile.ReadString('ReadMem','edtOffset2','');
    343.     edtOffset3.Text := iniFile.ReadString('ReadMem','edtOffset3','');
    344.     edtOffset4.Text := iniFile.ReadString('ReadMem','edtOffset4','');
    345.     edtOffset5.Text := iniFile.ReadString('ReadMem','edtOffset5','');
    346.     edtOffset6.Text := iniFile.ReadString('ReadMem','edtOffset6','');
    347.     edtOffset7.Text := iniFile.ReadString('ReadMem','edtOffset7','');
    348.     edtOffset8.Text := iniFile.ReadString('ReadMem','edtOffset8','');
    349.     edtOffset9.Text := iniFile.ReadString('ReadMem','edtOffset9','');
    350.     edtOffset10.Text := iniFile.ReadString('ReadMem','edtOffset10','');
    351.     edtOffset11.Text := iniFile.ReadString('ReadMem','edtOffset11','');
    352.     edtOffset12.Text := iniFile.ReadString('ReadMem','edtOffset12','');
    353.     chkOffset1.Checked := iniFile.ReadBool('ReadMem','chkOffset1',False);
    354.     cbOffset1.ItemIndex := iniFile.ReadInteger('ReadMem','cbOffset1',-1);
    355.     edtOffsetCount1.Text := iniFile.ReadString('ReadMem','edtOffsetCount1','2');
    356.     edtLoopCount1.Text := iniFile.ReadString('ReadMem','edtLoopCount1','500');
    357.     chkOffset2.Checked := iniFile.ReadBool('ReadMem','chkOffset2',False);
    358.     cbOffset2.ItemIndex := iniFile.ReadInteger('ReadMem','cbOffset2',-1);
    359.     edtOffsetCount2.Text := iniFile.ReadString('ReadMem','edtOffsetCount2','2');
    360.     edtLoopCount2.Text := iniFile.ReadString('ReadMem','edtLoopCount2','500');
    361.     chkOffset3.Checked := iniFile.ReadBool('ReadMem','chkOffset3',False);
    362.     cbOffset3.ItemIndex := iniFile.ReadInteger('ReadMem','cbOffset3',-1);
    363.     edtOffsetCount3.Text := iniFile.ReadString('ReadMem','edtOffsetCount3','2');
    364.     edtLoopCount3.Text := iniFile.ReadString('ReadMem','edtLoopCount3','500');
    365. end;
    366. function TfrmMain.ReadSingle(pAddress: Pointer): Single;
    367. var
    368.   tmp: Single;
    369.   ReadCount: Cardinal;
    370. begin
    371.   Result := 0;
    372.   if ProcessHandel = 0 then exit;
    373.   if pAddress = nil then exit;
    374.   ReadProcessMemory(ProcessHandel, pAddress, @tmp, SizeOf(tmp), ReadCount);
    375.   Result := tmp;
    376. end;
    377. function TfrmMain.ReadUnicode(pAddress: Pointer): string;
    378. var
    379.   tmp: array[0..31] of WideChar;
    380.   ReadCount: Cardinal;
    381. begin
    382.   Result := '';
    383.   if ProcessHandel = 0 then exit;
    384.   if pAddress = nil then exit;
    385.   ReadProcessMemory(ProcessHandel, pAddress, @tmp, SizeOf(tmp), ReadCount);
    386.   Result := tmp;
    387. end;
    388. procedure TfrmMain.ReadToListView(P: Pointer; Offset1, Offset2,
    389.   Offset3: Cardinal);
    390. var
    391.     pData: PFilterData;
    392. begin
    393.     New(pData);
    394.     ReadMemData(P, pData);
    395.     if cbFilterInProcess.Checked then
    396.     begin
    397.         if DataFilter(pData) then
    398.             AddListItem(pData,Offset1,Offset2,Offset3)
    399.         else
    400.             Dispose(pData);
    401.     end else
    402.         AddListItem(pData,Offset1,Offset2,Offset3);
    403. end;
    404. procedure TfrmMain.SaveSetting;
    405. var
    406.     iniFile: TIniFile;
    407.     strPath: string;
    408. begin
    409.     strPath := GetCurrentDir+'\Readmem.ini';
    410.     iniFile := TIniFile.Create(strPath);
    411.     with iniFile do
    412.     begin
    413.         WriteString('ReadMem', 'edtBaseAddress', edtBaseAddress.Text);
    414.         WriteString('ReadMem', 'edtOffset1', edtOffset1.Text);
    415.         WriteString('ReadMem', 'edtOffset2', edtOffset2.Text);
    416.         WriteString('ReadMem', 'edtOffset3', edtOffset3.Text);
    417.         WriteString('ReadMem', 'edtOffset4', edtOffset4.Text);
    418.         WriteString('ReadMem', 'edtOffset5', edtOffset5.Text);
    419.         WriteString('ReadMem', 'edtOffset6', edtOffset6.Text);
    420.         WriteString('ReadMem', 'edtOffset7', edtOffset7.Text);
    421.         WriteString('ReadMem', 'edtOffset8', edtOffset8.Text);
    422.         WriteString('ReadMem', 'edtOffset9', edtOffset9.Text);
    423.         WriteString('ReadMem', 'edtOffset10', edtOffset10.Text);
    424.         WriteString('ReadMem', 'edtOffset11', edtOffset11.Text);
    425.         WriteString('ReadMem', 'edtOffset12', edtOffset12.Text);
    426.         WriteBool('ReadMem', 'chkOffset1', chkOffset1.Checked);
    427.         WriteInteger('ReadMem', 'cbOffset1', cbOffset1.ItemIndex);
    428.         WriteString('ReadMem', 'edtOffsetCount1', edtOffsetCount1.Text);
    429.         WriteString('ReadMem', 'edtLoopCount1', edtLoopCount1.Text);
    430.         WriteBool('ReadMem', 'chkOffset2', chkOffset2.Checked);
    431.         WriteInteger('ReadMem', 'cbOffset2', cbOffset2.ItemIndex);
    432.         WriteString('ReadMem', 'edtOffsetCount2', edtOffsetCount2.Text);
    433.         WriteString('ReadMem', 'edtLoopCount2', edtLoopCount2.Text);
    434.         WriteBool('ReadMem', 'chkOffset3', chkOffset3.Checked);
    435.         WriteInteger('ReadMem', 'cbOffset3', cbOffset3.ItemIndex);
    436.         WriteString('ReadMem', 'edtOffsetCount3', edtOffsetCount3.Text);
    437.         WriteString('ReadMem', 'edtLoopCount3', edtLoopCount3.Text);
    438.     end;
    439. end;
    440. procedure TfrmMain.SetResultCount(const Value: Cardinal);
    441. begin
    442.   FResultCount := Value;
    443.   lbRecordCount.Caption := IntToStr(FResultCount);
    444. end;
    445. procedure TfrmMain.SetSelCount(const Value: Cardinal);
    446. begin
    447.   FSelCount := Value;
    448.   lbSelectCount.Caption := IntToStr(FSelCount);
    449. end;
    450. procedure TfrmMain.SetSingleFilter(bSingle: Boolean);
    451. begin
    452.     if bSingle then
    453.     begin
    454.         lbFitler.Visible := True;
    455.         edtFilter.Visible := True;
    456.         lbLargeOrEqual.Visible := False;
    457.         lbLessOrEqual.Visible := False;
    458.         edtLarge.Visible := False;
    459.         edtSmall.Visible := False;
    460.     end else
    461.     begin
    462.         lbFitler.Visible := False;
    463.         edtFilter.Visible := False;
    464.         lbLargeOrEqual.Visible := True;
    465.         lbLessOrEqual.Visible := True;
    466.         edtLarge.Visible := True;
    467.         edtSmall.Visible := True;
    468.     end;
    469. end;
    470. function TfrmMain.StrToFloatEx(str: string): Extended;
    471. var
    472.     tmp: string;
    473. begin
    474.     tmp := str;
    475.     if Pos('.', tmp) < 1 then
    476.         tmp := tmp + '.0';
    477.     try
    478.         Result := StrToFloat(tmp);
    479.     except
    480.         ShowMessage(''''+tmp+'''转换为浮点型时出错!');
    481.         Result := 0.0;
    482.     end;
    483. end;
    484. function TfrmMain.TruncEx(r: Real): Int64;
    485. var
    486.     tmp: string;
    487.     p: Integer;
    488. begin
    489.     tmp := FloatToStrEx(r);
    490.     p := Pos('.', tmp);
    491.     if p > 0 then
    492.         tmp := Copy(tmp, 0, p-1);
    493.     Result := StrToInt64(tmp);
    494. end;
    495. function TfrmMain.IsFloat(f: Extended): Boolean;
    496. var
    497.     tmp: Extended;
    498. begin
    499.     try
    500.         tmp := Trunc(f);
    501.         Result := True;
    502.     except
    503.         Result := False;
    504.     end;
    505. end;
    506. function TfrmMain.HexToCardinal(hex: string): Cardinal;
    507. begin
    508.     Result := StrToInt('$'+hex);
    509. end;
    510. procedure TfrmMain.lvResultClick(Sender: TObject);
    511. begin
    512.     SelCount := lvResult.SelCount;
    513. end;
    514. procedure TfrmMain.lvResultResize(Sender: TObject);
    515. var
    516.     ColWidth: Integer;
    517.     tmp: Integer;
    518. begin
    519.     ColWidth := 30;
    520.     tmp := lvResult.Width div 25;
    521.     if (tmp < (ColWidth+2)) then
    522.         tmp := ColWidth;
    523.     lvResult.Columns[0].Width := tmp *  4;
    524.     lvResult.Columns[1].Width := tmp *  3;
    525.     lvResult.Columns[2].Width := tmp *  3;
    526.     lvResult.Columns[3].Width := tmp *  3;
    527.     lvResult.Columns[4].Width := tmp *  3;
    528.     lvResult.Columns[5].Width := tmp *  3;
    529.     lvResult.Columns[6].Width := tmp *  3;
    530.     lvResult.Columns[7].Width := tmp *  3;
    531. end;
    532. procedure TfrmMain.AddListItem(pData: PFilterData; Offset1,Offset2,Offset3: Cardinal);
    533. var
    534.     lvItem: TListItem;
    535.     tmpStr: string;
    536. begin
    537.     lvItem := lvResult.Items.Add;
    538.     lvItem.Data := pData;
    539.     lvItem.Caption := pData.m_Text;
    540.    
    541.     lvItem.SubItems.Add(IntToStr(pData.m_Int));
    542.     lvItem.SubItems.Add(IntToStr(pData.m_UnSign));
    543.     tmpStr := FloatToStrEx(pData.m_Float);
    544.     lvItem.SubItems.Add(tmpStr);
    545.     tmpStr := FloatToStrEx(pData.m_Double);
    546.     lvItem.SubItems.Add(tmpStr);
    547.     lvItem.SubItems.Add(IntToHex(Offset1, 4));
    548.     lvItem.SubItems.Add(IntToHex(Offset2, 4));
    549.     lvItem.SubItems.Add(IntToHex(Offset3, 4));
    550.     ResultCount := ResultCount + 1;
    551. end;
    552. procedure TfrmMain.btClearClick(Sender: TObject);
    553. begin
    554.     ClearListView;
    555. end;
    556. procedure TfrmMain.btFilterInResultClick(Sender: TObject);
    557. var
    558.     I: Cardinal;
    559.     pData: PFilterData;
    560.     lstItemCount: Cardinal;
    561. begin
    562.     I := 0;
    563.     lstItemCount := lvResult.Items.Count;
    564.     while lstItemCount > I do
    565.     begin
    566.         pData := lvResult.Items.Item[I].Data;
    567.         if DataFilter(pData) = False then
    568.         begin
    569.             Dispose(pData);
    570.             lvResult.Items.Delete(I);
    571.             lstItemCount := lstItemCount -1;
    572.             ResultCount := ResultCount -1;
    573.         end else
    574.             I := I + 1;
    575.     end;
    576. end;
    577. procedure TfrmMain.btReFreshClick(Sender: TObject);
    578. begin
    579.     GetProcessInf;
    580. end;
    581. procedure TfrmMain.btSaveClick(Sender: TObject);
    582. begin
    583.     SaveSetting;
    584. end;
    585. procedure TfrmMain.btSaveToFileClick(Sender: TObject);
    586. var
    587.   i,j: Integer;
    588.   s: string;
    589.   StrList: TStringList;
    590.   SaveDlg: TSaveDialog;
    591.   SaveName: string;
    592. begin
    593.     with lvResult do
    594.     begin
    595.         StrList := TStringList.Create;
    596.         s := '文本'+#9+'整型'+#9+'无符整型'+#9+'浮点型'+#9+'双精度'+#9+'一级偏量'+#9+'二级偏量'+#9+'三级偏量';
    597.         StrList.Add(s);
    598.         for i := 0 to Items.Count-1 do
    599.         begin
    600.             s := Items[i].Caption;
    601.             for j := 1 to Columns.Count-1 do
    602.             begin
    603.                 s := s + #9 + items[i].subitems[j-1];
    604.             end;
    605.             StrList.Add(s);
    606.         end;
    607.     end;
    608.     SaveDlg := TSaveDialog.Create(nil);
    609.     SaveDlg.Filter := 'txt';
    610.     if SaveDlg.Execute(self.Handle) = False then exit;
    611.     SaveName := SaveDlg.FileName + '.' + SaveDlg.Filter;
    612.     SaveDlg.Free;
    613.     StrList.SaveToFile(SaveName);
    614.     StrList.Free;
    615. end;
    616. procedure TfrmMain.btSelectClick(Sender: TObject);
    617. begin
    618.     MessageBox(self.Handle, '作者:ABC'+#13+'QQ:67217629', '内存遍历ABC', MB_OKCANCEL);
    619. end;
    620. procedure TfrmMain.btStartClick(Sender: TObject);
    621. var
    622.     I,J,K,L: Integer;
    623.     P,BaseAddress: Pointer;
    624.     tmpCardinal: Cardinal;
    625.     Offset1, Offset2, Offset3: Cardinal;
    626. begin
    627.     if ProcessHandel = 0 then
    628.     begin
    629.         ShowMessage('请选择要操作的进程.');
    630.         cbProcess.SetFocus;
    631.         exit;
    632.     end;
    633.     if edtBaseAddress.Text = '' then
    634.     begin
    635.         ShowMessage('请设置基址.');
    636.         edtBaseAddress.SetFocus;
    637.         exit;
    638.     end;
    639.     BaseAddress := Pointer(HexToCardinal(edtBaseAddress.Text));
    640.     I := 0; J := 0; K := 0;
    641.     if chkOffset1.Checked = False then
    642.     begin
    643.         P := BaseAddress;
    644.         Offset1 := 0; Offset2 := 0; Offset3 := 0;
    645.         for L := 0 to 11 do
    646.         begin
    647.             if P = nil then Break;
    648.             if aryEdit[L].Text = '' then Break;
    649.             P := ReadPointer(P);
    650.             tmpCardinal := HexToCardinal(aryEdit[L].Text);
    651.             P := Pointer(Cardinal(P) + tmpCardinal);
    652.         end;
    653.         ReadToListView(P, Offset1, Offset2, Offset3);
    654.         Exit;
    655.     end;
    656.     for I := 0 to StrToInt(edtLoopCount1.Text) do
    657.     begin
    658.         if chkOffset2.Checked = False then
    659.         begin
    660.             P := BaseAddress;
    661.             Offset1 := 0; Offset2 := 0; Offset3 := 0;
    662.             for L := 0 to 11 do
    663.             begin
    664.                 if P = nil then Break;
    665.                 if aryEdit[L].Text = '' then Break;
    666.                 P := ReadPointer(P);
    667.                 tmpCardinal := HexToCardinal(aryEdit[L].Text);
    668.                 if L = cbOffset1.ItemIndex then
    669.                 begin
    670.                     Offset1 := HexToCardinal(edtOffsetCount1.Text)*I;
    671.                     tmpCardinal := tmpCardinal + Offset1;
    672.                 end;
    673.                 P := Pointer(Cardinal(P) + tmpCardinal);
    674.             end;
    675.             ReadToListView(P, Offset1, Offset2, Offset3);
    676.             Continue;
    677.         end;
    678.         for J := 0 to StrToInt(edtLoopCount2.Text) do
    679.         begin
    680.             if chkOffset3.Checked = False then
    681.             begin
    682.                 P := BaseAddress;
    683.                 Offset1 := 0; Offset2 := 0; Offset3 := 0;
    684.                 for L := 0 to 11 do
    685.                 begin
    686.                     if P = nil then Break;
    687.                     if aryEdit[L].Text = '' then Break;
    688.                     P := ReadPointer(P);
    689.                     tmpCardinal := HexToCardinal(aryEdit[L].Text);
    690.                     if L = cbOffset1.ItemIndex then
    691.                     begin
    692.                         Offset1 := HexToCardinal(edtOffsetCount1.Text)*I;
    693.                         tmpCardinal := tmpCardinal + Offset1;
    694.                     end;
    695.                     if L = cbOffset2.ItemIndex then
    696.                     begin
    697.                         Offset2 := HexToCardinal(edtOffsetCount2.Text)*J;
    698.                         tmpCardinal := tmpCardinal + Offset2;
    699.                     end;
    700.                     P := Pointer(Cardinal(P) + tmpCardinal);
    701.                 end;
    702.                 ReadToListView(P, Offset1, Offset2, Offset3);
    703.                 Continue;
    704.             end;
    705.             for K := 0 to StrToInt(edtLoopCount3.Text) do
    706.             begin
    707.                 P := BaseAddress;
    708.                 Offset1 := 0; Offset2 := 0; Offset3 := 0;
    709.                 for L := 0 to 11 do
    710.                 begin
    711.                     if P = nil then Break;
    712.                     if aryEdit[L].Text = '' then Break;
    713.                     P := ReadPointer(P);
    714.                     tmpCardinal := HexToCardinal(aryEdit[L].Text);
    715.                     if L = cbOffset1.ItemIndex then
    716.                     begin
    717.                         Offset1 := HexToCardinal(edtOffsetCount1.Text)*I;
    718.                         tmpCardinal := tmpCardinal + Offset1;
    719.                     end;
    720.                     if L = cbOffset2.ItemIndex then
    721.                     begin
    722.                         Offset2 := HexToCardinal(edtOffsetCount2.Text)*J;
    723.                         tmpCardinal := tmpCardinal + Offset2;
    724.                     end;
    725.                     if L = cbOffset3.ItemIndex then
    726.                     begin
    727.                         Offset3 := HexToCardinal(edtOffsetCount3.Text)*K;
    728.                         tmpCardinal := tmpCardinal + Offset3;
    729.                     end;
    730.                     P := Pointer(Cardinal(P) + tmpCardinal);
    731.                 end;
    732.                 ReadToListView(P, Offset1, Offset2, Offset3);
    733.             end;
    734.         end;
    735.     end;
    736. end;
    737. procedure TfrmMain.chkOffset2Click(Sender: TObject);
    738. begin
    739.     if chkOffset2.Checked then
    740.     begin
    741.         cbOffset2.Enabled := True;
    742.         edtOffsetCount2.Enabled := True;
    743.         edtLoopCount2.Enabled := True;
    744.         chkOffset3.Enabled := True;
    745.         cbOffset2.ItemIndex := cbOffset1.ItemIndex+1;
    746.     end else
    747.     begin
    748.         cbOffset2.Enabled := False;
    749.         edtOffsetCount2.Enabled := False;
    750.         edtLoopCount2.Enabled := False;
    751.         chkOffset3.Checked := False;
    752.         chkOffset3.Enabled := False;
    753.     end;
    754. end;
    755. procedure TfrmMain.chkOffset3Click(Sender: TObject);
    756. begin
    757.     if chkOffset3.Checked then
    758.     begin
    759.         cbOffset3.Enabled := True;
    760.         edtOffsetCount3.Enabled := True;
    761.         edtLoopCount3.Enabled := True;
    762.         cbOffset3.ItemIndex := cbOffset2.ItemIndex+1;
    763.     end else
    764.     begin
    765.         cbOffset3.Enabled := False;
    766.         edtOffsetCount3.Enabled := False;
    767.         edtLoopCount3.Enabled := False;
    768.     end;
    769. end;
    770. procedure TfrmMain.ClearListView;
    771. var
    772.     I: Integer;
    773. begin
    774.     for I := 0 to lvResult.Items.Count - 1 do
    775.     begin
    776.             Dispose(lvResult.Items.Item[I].Data);
    777.     end;
    778.     lvResult.Clear;
    779.     ResultCount := 0;
    780.     SelCount := 0;
    781. end;
    782. procedure TfrmMain.cbProcessChange(Sender: TObject);
    783. begin
    784.     if ProcessHandel <> 0 then CloseHandle(ProcessHandel);
    785.     ProcessHandel := GetSelProcessHandel;
    786. end;
    787. procedure TfrmMain.chkOffset1Click(Sender: TObject);
    788. var
    789.     I: Integer;
    790. begin
    791.     if chkOffset1.Checked then
    792.     begin
    793.         cbOffset1.Enabled := True;
    794.         edtOffsetCount1.Enabled := True;
    795.         edtLoopCount1.Enabled := True;
    796.         chkOffset2.Enabled := True;
    797.         for I := 0 to 11 do
    798.         begin
    799.             if aryEdit[I].Text = '' then Break;
    800.         end;
    801.         cbOffset1.ItemIndex := I-1;
    802.     end else
    803.     begin
    804.         cbOffset1.Enabled := False;
    805.         edtOffsetCount1.Enabled := False;
    806.         edtLoopCount1.Enabled := False;
    807.         chkOffset2.Checked := False;
    808.         chkOffset3.Checked := False;
    809.         chkOffset2.Enabled := False;
    810.         chkOffset3.Enabled := False;
    811.     end;
    812. end;
    813. function TfrmMain.DataFilter(pData: PFilterData): Boolean;
    814. var
    815.     tmpInt1, tmpInt2, tmpInt3: Int64;
    816.     tmpFloat1, tmpFloat2, tmpFloat3: Single;
    817.     tmpDouble1, tmpDouble2, tmpDouble3: Double;
    818. begin
    819.     Result := False;
    820.     tmpInt1:=0; tmpInt2:=0; tmpInt3:=0;
    821.     tmpFloat1:=0.0; tmpFloat2:=0.0; tmpFloat3:=0.0;
    822.     tmpDouble1:=0.0; tmpDouble2:=0.0; tmpDouble3:=0.0;
    823.     if rbText.Checked then
    824.     begin
    825.         if rbEqual.Checked then
    826.         begin
    827.             if chkTextMatch.Checked then
    828.                 Result := (Pos(edtFilter.Text, pData.m_Text) > 0)
    829.             else
    830.                 Result := (edtFilter.Text = pData.m_Text);
    831.             exit;
    832.         end;
    833.         exit;
    834.     end;
    835.     if rbInt.Checked then
    836.     begin
    837.         if rbEqual.Checked then
    838.         begin
    839.             Result := (pData.m_Int = StrToInt(edtFilter.Text));
    840.             exit;
    841.         end;
    842.         if rbLarge.Checked then
    843.         begin
    844.             Result := (pData.m_Int > StrToInt(edtFilter.Text));
    845.             exit;
    846.         end;
    847.         if rbLess.Checked then
    848.         begin
    849.             Result := (pData.m_Int < StrToInt(edtFilter.Text));
    850.             exit;
    851.         end;
    852.         if rbUnequal.Checked then
    853.         begin
    854.             Result := (pData.m_Int <> StrToInt(edtFilter.Text));
    855.             exit;
    856.         end;
    857.         if rbLargeOrEqual.Checked then
    858.         begin
    859.             Result := (pData.m_Int >= StrToInt(edtFilter.Text));
    860.             exit;
    861.         end;
    862.         if rbLessOrEqual.Checked then
    863.         begin
    864.             Result := (pData.m_Int <= StrToInt(edtFilter.Text));
    865.             exit;
    866.         end;
    867.         if rbBetween.Checked then
    868.         begin
    869.             Result := ((pData.m_Int >= StrToInt(edtSmall.Text)) And
    870.                         (pData.m_Int <= StrToInt(edtLarge.Text)));
    871.             exit;
    872.         end;
    873.         exit;
    874.     end;
    875.     if rbUnSign.Checked then
    876.     begin
    877.         if rbEqual.Checked then
    878.         begin
    879.             Result := (pData.m_UnSign = StrToInt(edtFilter.Text));
    880.             exit;
    881.         end;
    882.         if rbLarge.Checked then
    883.         begin
    884.             Result := (pData.m_UnSign > StrToInt(edtFilter.Text));
    885.             exit;
    886.         end;
    887.         if rbLess.Checked then
    888.         begin
    889.             Result := (pData.m_UnSign < StrToInt(edtFilter.Text));
    890.             exit;
    891.         end;
    892.         if rbUnequal.Checked then
    893.         begin
    894.             Result := (pData.m_UnSign <> StrToInt(edtFilter.Text));
    895.             exit;
    896.         end;
    897.         if rbLargeOrEqual.Checked then
    898.         begin
    899.             Result := (pData.m_UnSign >= StrToInt(edtFilter.Text));
    900.             exit;
    901.         end;
    902.         if rbLessOrEqual.Checked then
    903.         begin
    904.             Result := (pData.m_UnSign <= StrToInt(edtFilter.Text));
    905.             exit;
    906.         end;
    907.         if rbBetween.Checked then
    908.         begin
    909.             Result := ((pData.m_UnSign >= StrToInt(edtSmall.Text)) And
    910.                         (pData.m_UnSign <= StrToInt(edtLarge.Text)));
    911.             exit;
    912.         end;
    913.         exit;
    914.     end;
    915.     if rbFloat.Checked then
    916.     begin
    917.         if IsFloat(pData.m_Float) = False then Exit;
    918.         
    919.         if chkFloatToInt.Checked then
    920.         begin
    921.             tmpInt1 := TruncEx(pData.m_Float);
    922.             tmpInt2 := Trunc(StrToFloatEx(edtFilter.Text));
    923.         end else
    924.         begin
    925.             tmpFloat1 := pData.m_Float;
    926.             tmpFloat2 := StrToFloatEx(edtFilter.Text);
    927.         end;
    928.         if rbEqual.Checked then
    929.         begin
    930.             if chkFloatToInt.Checked then
    931.                 Result := (tmpInt1 = tmpInt2)
    932.             else
    933.                 Result := (tmpFloat1 = tmpFloat2);
    934.             exit;
    935.         end;
    936.         if rbLarge.Checked then
    937.         begin
    938.             if chkFloatToInt.Checked then
    939.                 Result := (tmpInt1 > tmpInt2)
    940.             else
    941.                 Result := (tmpFloat1 > tmpFloat2);
    942.             exit;
    943.         end;
    944.         if rbLess.Checked then
    945.         begin
    946.             if chkFloatToInt.Checked then
    947.                 Result := (tmpInt1 < tmpInt2)
    948.             else
    949.                 Result := (tmpFloat1 < tmpFloat2);
    950.             exit;
    951.         end;
    952.         if rbUnequal.Checked then
    953.         begin
    954.             if chkFloatToInt.Checked then
    955.                 Result := (tmpInt1 <> tmpInt2)
    956.             else
    957.                 Result := (tmpFloat1 <> tmpFloat2);
    958.             exit;
    959.         end;
    960.         if rbLargeOrEqual.Checked then
    961.         begin
    962.             if chkFloatToInt.Checked then
    963.                 Result := (tmpInt1 >= tmpInt2)
    964.             else
    965.                 Result := (tmpFloat1 >= tmpFloat2);
    966.             exit;
    967.         end;
    968.         if rbLessOrEqual.Checked then
    969.         begin
    970.             if chkFloatToInt.Checked then
    971.                 Result := (tmpInt1 <= tmpInt2)
    972.             else
    973.                 Result := (tmpFloat1 <= tmpFloat2);
    974.             exit;
    975.         end;
    976.         if rbBetween.Checked then
    977.         begin
    978.             if chkFloatToInt.Checked then
    979.             begin
    980.                 tmpInt2 := Trunc(StrToFloatEx(edtSmall.Text));
    981.                 tmpInt3 := Trunc(StrToFloatEx(edtLarge.Text));
    982.                 Result := ((tmpInt1 >= tmpInt2) And (tmpInt1 <= tmpInt3));
    983.             end else
    984.             begin
    985.                 tmpFloat2 := StrToFloatEx(edtSmall.Text);
    986.                 tmpFloat3 := StrToFloatEx(edtLarge.Text);
    987.                 Result := ((tmpFloat1 >= tmpFloat2) And (tmpFloat1 <= tmpFloat3));
    988.             end;
    989.             exit;
    990.         end;
    991.         exit;
    992.     end;
    993.     if rbDouble.Checked then
    994.     begin
    995.         if IsFloat(pData.m_Double) = False then Exit;
    996.         
    997.         if chkFloatToInt.Checked then
    998.         begin
    999.             tmpInt1 := TruncEx(pData.m_Double);
    1000.             tmpInt2 := Trunc(StrToFloatEx(edtFilter.Text));
    1001.         end else
    1002.         begin
    1003.             tmpDouble1 := pData.m_Double;
    1004.             tmpDouble2 := StrToFloatEx(edtFilter.Text);
    1005.         end;
    1006.         if rbEqual.Checked then
    1007.         begin
    1008.             if chkFloatToInt.Checked then
    1009.                 Result := (tmpInt1 = tmpInt2)
    1010.             else
    1011.                 Result := (tmpDouble1 = tmpDouble2);
    1012.             exit;
    1013.         end;
    1014.         if rbLarge.Checked then
    1015.         begin
    1016.             if chkFloatToInt.Checked then
    1017.                 Result := (tmpInt1 > tmpInt2)
    1018.             else
    1019.                 Result := (tmpDouble1 > tmpDouble2);
    1020.             exit;
    1021.         end;
    1022.         if rbLess.Checked then
    1023.         begin
    1024.             if chkFloatToInt.Checked then
    1025.                 Result := (tmpInt1 < tmpInt2)
    1026.             else
    1027.                 Result := (tmpDouble1 < tmpDouble2);
    1028.             exit;
    1029.         end;
    1030.         if rbUnequal.Checked then
    1031.         begin
    1032.             if chkFloatToInt.Checked then
    1033.                 Result := (tmpInt1 <> tmpInt2)
    1034.             else
    1035.                 Result := (tmpDouble1 <> tmpDouble2);
    1036.             exit;
    1037.         end;
    1038.         if rbLargeOrEqual.Checked then
    1039.         begin
    1040.             if chkFloatToInt.Checked then
    1041.                 Result := (tmpInt1 >= tmpInt2)
    1042.             else
    1043.                 Result := (tmpDouble1 >= tmpDouble2);
    1044.             exit;
    1045.         end;
    1046.         if rbLessOrEqual.Checked then
    1047.         begin
    1048.             if chkFloatToInt.Checked then
    1049.                 Result := (tmpInt1 <= tmpInt2)
    1050.             else
    1051.                 Result := (tmpDouble1 <= tmpDouble2);
    1052.             exit;
    1053.         end;
    1054.         if rbBetween.Checked then
    1055.         begin
    1056.             if chkFloatToInt.Checked then
    1057.             begin
    1058.                 tmpInt2 := Trunc(StrToFloatEx(edtSmall.Text));
    1059.                 tmpInt3 := Trunc(StrToFloatEx(edtLarge.Text));
    1060.                 Result := ((tmpInt1 >= tmpInt2) And (tmpInt1 <= tmpInt3));
    1061.             end else
    1062.             begin
    1063.                 tmpDouble2 := StrToFloatEx(edtSmall.Text);
    1064.                 tmpDouble3 := StrToFloatEx(edtLarge.Text);
    1065.                 Result := ((tmpFloat1 >= tmpDouble2) And (tmpFloat1 <= tmpDouble3));
    1066.             end;
    1067.             exit;
    1068.         end;
    1069.         exit;
    1070.     end;
    1071. end;
    1072. function TfrmMain.DebugPrivilege(bEnable: Boolean): Boolean;
    1073. var
    1074.     hToken: THandle;
    1075.     TokenPrivileges: TTokenPrivileges;
    1076.     RetLength: DWORD;
    1077. begin
    1078.     Result := true;
    1079.     If OpenProcessToken(GetCurrentProcess(),
    1080.                         TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES,
    1081.                         hToken) = false then
    1082.     Begin
    1083.         ShowMessage('权限提升失败!');
    1084.         exit;
    1085.     End;
    1086.     TokenPrivileges.PrivilegeCount := 1;
    1087.     If bEnable Then
    1088.         TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    1089.     Else
    1090.         TokenPrivileges.Privileges[0].Attributes := 0;
    1091.     LookupPrivilegeValue(nil, 'SeDebugPrivilege', TokenPrivileges.Privileges[0].Luid);
    1092.     AdjustTokenPrivileges(hToken, False, TokenPrivileges,
    1093.                             sizeof(TokenPrivileges),TokenPrivileges,RetLength);
    1094.     CloseHandle(hToken);
    1095. end;
    1096. end.
    复制代码
    游客,如果您要查看本帖隐藏内容请回复

    该用户从未签到

    topzhp 发表于 2010-4-17 18:03:08 | 显示全部楼层
    看起来不错,顶一个!多谢了!

    该用户从未签到

    topzhp 发表于 2010-4-17 18:04:52 | 显示全部楼层
    都不敢乱下了,才下了一个工具,那些辅助版块都进不去了。郁闷!

    该用户从未签到

    我叫阿小莫 发表于 2010-5-28 18:47:02 | 显示全部楼层
    瞧一瞧哈....

    该用户从未签到

    bamlan 发表于 2010-6-25 15:11:52 | 显示全部楼层
    支持一下....
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

    本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

    QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

    Copyright © 2001-2023 Discuz! Team. GMT+8, 2024-12-22 20:28 , File On Powered by Discuz! X3.49

    快速回复 返回顶部 返回列表