ããã«ãç§ã¯äºçŽãããŸããã¢ããªã±ãŒã·ã§ã³/ãããã¬ãŒã«å察ããŠãæåŸã®ãã®ãåžžã«åã¡ãŸã:)
ããããæèœãªå°é家ãããã䜿çšãããã®ãããªå°é家ã«å¯ŸåŠããããšã¯å®è³ªçã«åœ¹ã«ç«ããªãå Žåã«ã®ã¿ã§ãïŒãã¡ãããå°ãªããšãåãè³æ ŒãæããªãéãïŒã
確ãã«ãå®è·µã瀺ãããã«ãæèœãªå°é家ã¯åœŒãã®ããã«é¢çœããªãä»äºã«åŸäºããã圌ãã¯ãŸã ç§åŠã®è±åŽå²©ãããã£ãŠããªãããã€ãã®æãããªããªãã¯ã«ã€ãŸãããããããªããªããŒã¹ãªããŒã¹ã®å®¹èµŠã«ä»»ããŠããŸãã
ããã§ã¯ãéåžžã«åçŽåããã圢ã§ã®ã¿æ€èšãããã®ã§ãã
æãåçŽãªShareWareïŒ
売ãããšã«æ±ºãããœãããŠã§ã¢ããããšããŸãã ç°¡åã«ããããã«ã空ã®ãã©ãŒã ããã®éåžžã®VCLã¢ããªã±ãŒã·ã§ã³ãšããŸãïŒç©ºã§ã¯ãããŸããããå šäœãç»åã«ãªã£ãŠããŸãïŒã販売ããããšæããŸãã äžè©±ãããå¿ èŠãããæåã®è³ªåã¯ãç§ãã¡ã®åçããããæ¯æã£ã人ã ãã«èŠããããã«ããæ¹æ³ã§ããïŒ ããæ£ç¢ºã«-ãã©ã€ã¢ã«ãŠãŒã¶ãŒãšæ³çãŠãŒã¶ãŒãåºå¥ããæ¹æ³ã¯ïŒ
æãæãããªè§£æ±ºçãéµã§ãã ãã©ã€ã¢ã«ãŠãŒã¶ãŒã¯åœŒãç¥ãããå®éã®ãéã§æ¯æããè¡ã£ãåæ³çãªãŠãŒã¶ãŒã¯ãã¢ããªã±ãŒã·ã§ã³ã®åæ³çãªã³ããŒãã¢ã¯ãã£ãã«ããŠåçã楜ããããšãã§ããŸãã
ããŒã¯ãšãŠãéèŠã§ãã
æ°ããVCLã¢ããªã±ãŒã·ã§ã³ãäœæããTImageãã©ãŒã ã«ç»åãã¹ããŒããVisibleãFalseã«èšå®ããŸãã 次ã«ã2ã€ã®TEditããã©ãŒã ã«é 眮ããŸãã1ã€ç®ã¯ãŠãŒã¶ãŒåçšã2ã€ç®ã¯ã¢ã¯ãã£ããŒã·ã§ã³ã³ãŒãçšã§ãã ããŠã2ã€ã®ãã¿ã³-ã¢ããªã±ãŒã·ã§ã³ãéããŠã¢ã¯ãã£ãã«ããŸãã
ããŠããã®ãããªãã®ïŒ
ãã®åŸãããããã·ãŒã¯ã¬ãããã¢ã¯ãã£ããŒã·ã§ã³ã³ãŒããèšè¿°ããŸãã
function TForm1.GenerateSerial(const AppUserName: string): string; const MagicSerialMask: int64 = $C5315E6121543992; var I: Integer; SN: int64; RawSN: string; begin SN := 0; Result := ''; for I := 1 to Length(AppUserName) do begin Inc(SN, Word(AppUserName[I])); SN := SN * 123456; end; Sn := SN xor MagicSerialMask; RawSN := IntToHex(SN, 16); for I := 1 to 16 do if ((I - 1) mod 4 = 0) and (I > 1) then Result := Result + '-' + RawSN[I] else Result := Result + RawSN[I]; end; procedure TForm1.btnCheckSerialClick(Sender: TObject); begin if edSerial.Text <> GenerateSerial(edAppUserName.Text) then Application.MessageBox(' ', PChar(Application.Title), MB_OK or MB_ICONERROR) else begin Image1.Visible := True; Label1.Visible := False; Label2.Visible := False; Label3.Visible := False; edAppUserName.Visible := False; edSerial.Visible := False; btnCancel.Visible := False; btnCheckSerial.Visible := False; end; end;
ã³ãŒãã®æ¬è³ªã¯æ¬¡ã®ãšããã§ãã
ãŠãŒã¶ãŒåã«åºã¥ããŠãã¢ããªã±ãŒã·ã§ã³ã¯ç¹å®ã®ã·ãªã¢ã«çªå·ãçæããå ¥åãããŠãŒã¶ãŒãšæ¯èŒããŸãã ãã¹ãŠãæ£åžžã§ããå Žåãã¢ã¯ãã£ããŒã·ã§ã³ã«é¢äžãããã¹ãŠã®ã³ã³ãããŒã«ãåé€ããããŠãŒã¶ãŒãèŠãããšæã£ãŠããç»åã衚瀺ãããŸãã
ãããèšã£ãŠã¿ãŸãããïŒ
ïŒãŸã...ç§ãæåã«èŠã€ãããã®:)
æäœåŸããitãã¯ããŸããŸãªã·ã§ã¢ãŠã§ã¢ãµã€ãã§å ¬éãããããã°ã©ããã©ãŒã©ã ãžã®ãªã³ã¯ããtest plz protectionããšãã圢åŒã®ãããã¯ã§æäŸãããããšããããŸãã
ãããŠãã¯ã©ãã«ãŒã¯ã©ã®ããã«èŠããŸããïŒ
圌ã¯ãããã¬ãŒã䜿ãïŒç°¡åã«ããããã«ãåãOlly Debugã䜿ããŸãïŒã次ã®å³ãèŠãŸãïŒ
圌ã¯ã¢ããªã±ãŒã·ã§ã³ã³ãŒããæã£ãŠããŸãããããœãããŠã§ã¢ã®ããã£ãã§ã³ããŒããéå§ãããšããå žåçãªééãããããŸã-ééã£ãããŒã«é¢ãããã€ã¢ãã°ã衚瀺ããŸãã
ããã¯ã¯ã©ãã«ãŒã«äœãäžããŸããïŒ
圌ã¯BPãMessageBoxAåŒã³åºãã«é 眮ããã¢ããªã±ãŒã·ã§ã³ãèµ·åããŠãã®ã¡ââãã»ãŒãžã®åŒã³åºãããã£ããããŸãããã®åŸããOKããã¿ã³ãã¯ãªãã¯ããããšã§ããšã©ãŒãåŒã³åºãããã³ãŒãã«æ»ãããšãã§ããŸãããã®åŒã³åºããçºçããŸãïŒ
åçã§ã¯ãããã°ã©ã ã®æ±ºå®ç¹ãæå笊ã§åŒ·èª¿è¡šç€ºãããŠããŸãã
圌ãããã¹ãããšã¯ãJMPã®JEåœä»€ãä¿®æ£ããã·ãªã¢ã«ã³ãŒãæ€èšŒãç¡å¹ã«ããã¢ããªã±ãŒã·ã§ã³ãã¢ã¯ãã£ãåããããšãã«ã®ã¿å®è¡ãããã³ãŒãé åãžã®æå¹ãªé·ç§»ã確ä¿ããããšã ãã§ãã
ã©ããããããæ確ã§ã¯ãªãã§ãããïŒ
ããã§ã¯ãDelphiãããã¬ãŒã®åçã次ã«ç€ºããŸãã
ããã§ã¯ããããã°ã®ããã«ã³ãŒããããç解ãããããã¢ãã¬ã¹ã解èªããŠèªã¿åãå¯èœãªåœ¢åŒã«ãããããã³ãŒãã®èªã¿åãããã䟿å©ã«ãªããŸãã ããšãã°ã決å®ãè¡ãããã¢ãã¬ã¹0x475729ã«å°éããåã«ãTEditsããããã¹ããåä¿¡ãããGenerateSerialããã·ãŒãžã£ãåŒã³åºãããããšãã¯ã£ãããšããããŸãã
ã¯ã©ãã«ãŒã«ã¯ãã®ãããªæ å ±ããªããåã®ç»åã«èŠãããããã«ãåæã®ããã«ç»åãå€å°ç解ã§ããããã«ããããã«ããã¹ãŠã®åŒã³åºããåæããå¿ èŠããããŸãã å®ã¯ãããã§å°ãèªåŒµããŸãããå®éãã¢ããªã±ãŒã·ã§ã³ãããã¯ããŒã«ã䜿çšããŠéåžžã«ç°¡åã«æ§ç¯ãããŸããã...äžéšã®äººã ã¯ãã€ã«ã«ã®ã·ã¹ãã ã¢ãžã¥ãŒã«ããããã°ããããšåªåããããšããããŸãã
ããŠãã¹ã¯ãªãŒã³ã·ã§ããã®0x475729ã«ãããã¥ã¢ã³ã¹ã«ã¯ã2ã€ã®ç°ãªãæ瀺ããããŸã-JZãšJEããããã¯éã¢ã»ã³ãã©ãŒã解éãããã¥ã¢ã³ã¹ã§ãããåäžã§ãã
ç§ã«äœåºŠãè¡šæãããŠããèå³æ·±ãã¢ãããŒãããããŸãã
ããã§å°ãäžã«ãç§ã¯BPãMessageBoxAã«çœ®ãããšãçºè¡šããŸããã圌ãã¯ãMessageBoxWãåŒã³åºããšåŒã³åºãããã£ããã§ããªãããšãæããŠãããŸãã ãã®ã¹ããŒãã¡ã³ãã¯ããã©ã¹ã®ä»ããå å®ãª4ã«å¯Ÿãããã®ã§ããã¯ãã確ãã«ãã¢ããªã±ãŒã·ã§ã³ãUnicode APIãåŒã³åºããšããã¬ãŒã¯ããŠã³ã§å°ããªãã¹ããããŸããããã¥ã¢ã³ã¹ããããŸãã MessageBoxåŒã³åºãã¹ã¿ãã¯å šäœãå±éããŠã¿ãŸãããã
ãããã©ã®ãããªé¢çœãã¹ããŒã ã§ããããèŠãŠãã ããïŒ
MessageBoxA-> MessageBoxExA-> MessageBoxTimeOutA-> MessageBoxTimeOutW-> SoftModalMessageBoxïŒïŒ
ãã®ãããå¿ èŠãªåŒã³åºãããã£ããããããã«ãMessageBoxWé¢æ°ãåŒã³åºãããšã§ããªã¹ããããé¢æ°ã®ããããã«BPãåŒã³åºãããšãã§ããŸãïŒéåžžã¯MessageBoxTimeOutWã§ååã§ãïŒã
埮åŠãªãã¥ã¢ã³ã¹ããããŸãããDelphiã«ã¯ãŠã£ã³ããŠã衚瀺ããä»ã®æ¹æ³ããããŸãã
ããŠãããšãã°ShowMessageïŒïŒã ãã®ã¡ãœããã¯ãMessageBox APIãåŒã³åºããŸããã
ãã®ã¡ãœããã¯ãå¿ èŠã«å¿ããŠãã¿ã³ãé 眮ãããå¥ã®ãã©ãŒã ãäœæãã圢ã§å®å šã«å®è£ ãããäžè¬ã«ãããã¯VCLèªäœã®å éšã§ããããããã¬ãŒã§ã¯äœãæ確ã§ã¯ãªããšããçç±ãèãã®ã¯ååã«é¢çœãã§ã
ãã®åŒã³åºããShowWindow APIã«åºã¥ããŠããªãå Žåã¯ããã®ããã«ãªããŸãããã®åŒã³åºããããå¿ èŠãªã³ãŒãã®ã¹ã¿ãã¯ã«é²ã¿ãŸãã
察話ã®èª²é¡ã¯ãŸã ãããŸããããŸã£ããåãæçããããŸãã ãã®ãã¹ãŠã¯ãå€ãã®æéãªãã§æ€åºãããŸãã
ãããã£ãŠãããŒãããã¯ã«æåã®çµè«ãå°ããŸãã
ãã®ãã§ãã¯ã®çŽåŸã«å€±æããã³ãŒããã§ãã¯ã«é¢ããã¡ãã»ãŒãžãåŒã³åºãããšã¯ãæªæã®å åã§ãã
ã¢ããªã±ãŒã·ã§ã³ã®æŽåæ§å¶åŸ¡ã®å°å ¥ïŒ
ããã§ã¯-圌ãã¯ç§ãã¡ããããã³ã°ããã¢ããªã±ãŒã·ã§ã³ã®1ãã€ãã ããå€æŽããŸããã ä»ãç§ãã¡ã®æ¥œããåçã¯ãå®å šã«ç¡æã§å©çšã§ããŸãã
æ²ããããšã«ãéèŠã§ã¯ãªã-ç§ãã¡ã¯æŠã...
ãããã³ã°ã¯ãã¢ããªã±ãŒã·ã§ã³æ¬äœã®çŽæ¥ç·šéãéããŠçºçããŸããã
ãã®ãããã¿ã¹ã¯ã¯æé·ããŸããããœãŒã¹ã³ãŒãã®æŽåæ§ã®æ€èšŒãæäŸããããšã§ãã
æãããããã«èãããŸãããå®éã«ã¯å®éã«ã¯äžå¯èœã§ã:)
ãã®ãã¹ãã«ã¯äœãé©çšã§ããŸããïŒ
æµè¡èªã¯ãããããããŸããããžã¿ã«çœ²åããã£ã¹ã¯äžã®ãã¡ã€ã«ã®ã€ã¡ãŒãžã®ç¢ºèªããã§ãã¯ãµã ã§ã³ãŒãã»ã¯ã·ã§ã³ããã§ãã¯ããŸãã ãã¹ãŠã空ã§ã-çµå±ããšã«ãããã¡ã¢ãªå ã®ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã®çŸåšã®å€ãååŸããå¿ èŠãçããŸã...
ããŠãç§ãã¡ã¯ããžã¿ã«çœ²åãèŠãŠããŸãã 圌女ã¯ãæåã«æ¯æã£ãã 次ã«ãååã«å¯ŸããŠè匱ãªWinVerifyTrusté¢æ°ã®APIãåŒã³åºããŠãã§ãã¯ããŸãã 第äžã«ãImageRemoveCertificateã䜿çšããŠéåžžã®æ¹æ³ã§ç°¡åã«åé€ã§ããŸãã
éžæè¢ã§ã¯ãããŸããããã£ã¹ã¯äžã®ãã¡ã€ã«ã®ç»åã確èªããã«ã¯ã©ãããã°ããã§ããïŒ
ããã§ãããã¹ãŠãæ²ããã§ãã èŠãŠãå®è¡å¯èœãã¡ã€ã«ã«ããããé©çšãããŠããã®ã§ããã£ã¹ã¯äžã®ã€ã¡ãŒãžãšæ¯èŒããŠãããå€æããåãParamStrïŒ0ïŒïŒããšãã°ïŒãä»ããŠçŸåšã®ãã¡ã€ã«ãžã®ãã¹ãååŸãããã®ãã¹ã§ãã¡ã€ã«ãéããŠãã§ãã¯ãéå§ããŸããã...
ãã ããOpenFile / CreateFileãåŒã³åºã段éã§ãã¯ã©ãã«ãŒã¯å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒã®ãã¹ãå ã®å€æŽãããŠããªãã€ã¡ãŒãžãžã®ãã¹ã«çœ®ãæãããã¹ãŠã®ãã§ãã¯ããã©ã¬ã¹ããééããŸãã
å¥ã®èå³æ·±ãç¹ããããŸãã ãã ããã¢ããªã±ãŒã·ã§ã³ããã£ã¹ã¯ã«ä¿åããŠå€æŽããããšã¯ã§ããŸããã ããŒããŒã®ãããªãã®ããããŸãã 圌ãã®æ¬è³ªã¯ãããã»ã¹ãéå§ããã¡ã¢ãªå ã®ã¢ããªã±ãŒã·ã§ã³æ¬äœãçŽæ¥å€æŽãããšããäºå®ã«ãããŸãã
ããšãã°ãåã®èšäºãããããã¬ãŒãåãåºããããã䜿çšããŠéæ³ã®çµµã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšã³ããªãã€ã³ãã«å°éããã次ã®ã³ãŒããå®è¡ããŸãã
procedure TTestDebugger.OnBreakPoint(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord; BreakPointIndex: Integer; var ReleaseBreakpoint: Boolean); var JmpOpcode: Byte; begin if ExceptionRecord.ExceptionAddress = Pointer(FCore.DebugProcessData.EntryPoint) then begin JmpOpcode := $EB; FCore.WriteData(Pointer($475729), @JmpOpcode, 1);
ãã£ã¹ã¯äžã®ã¢ããªã±ãŒã·ã§ã³ã¯å€æŽãããŸããããJEåœä»€ã®ä»£ããã«ãèšé²ãããJMPåœä»€ã«ããçŽæ¥ãžã£ã³ããå®è¡ãããŸãã ãã§ã«ããªãæ²ããã§ãããªããªã ãã®å ŽåãæŽåæ§ããã§ãã¯ããããã®æåã®2ã€ã®ãªãã·ã§ã³ã¯æ©èœããªãããšãä¿èšŒãããŠããŸãã
3çªç®ã®ãªãã·ã§ã³ã¯æ®ããã¢ããªã±ãŒã·ã§ã³æ¬äœã®ã³ãŒãã»ã¯ã·ã§ã³ãçŽæ¥ãã§ãã¯ããŸãã
ããã¯å®è£ ã®ããã®ããªããªãœãŒã¹ãæ¶è²»ãããªãã·ã§ã³ã§ããã次ã®çç±ã§åžžã«æåã«ã€ãªãããšã¯éããŸããã
ãŸãããã§ãã¯ãµã å®æ°ã ã¢ããªã±ãŒã·ã§ã³ã®æ¬äœã«ä¿åãããŠããå Žåãã¯ã©ãã«ãŒã¯ããããæ£ãããã®ã«å€æŽããŸãã ïŒããŒãããã¯ã®2çªç®ã®çµè«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒããããã¯ã®CRCå®æ°ã§ããããŒã³ãæªãã§ãïŒã
第äºã«ãèšäºã®åŸåã§ã¯ãMIA-Memory Breakpointã«ã€ããŠèª¬æããŸããã ããã¯ãã³ãŒãã®æŽåæ§ãã§ãã¯ãæ€åºããããã®çæ³çãªã¡ã«ããºã ã§ãïŒããã«æèœãªHBP-Hardware BreakPointãèæ ®ããªãå ŽåïŒã
åçŽã«æ©èœããŸããã³ãŒãã®çŸåšã®ã»ã¯ã·ã§ã³ãä¿è·ã¡ã«ããºã ã«ãã£ãŠå¶åŸ¡ãããŠããçããããå ŽåãMVRãŸãã¯HBPããã³ã°ããŠãã³ãŒãæŽåæ§ãã§ãã¯èªäœã®å Žæãå€æããŸãã
ãã®ãããªãã§ãã¯ãæ€åºããããšããããã«ãã£ãŠãç¡å¹ã«ãªããŸãã
ããŠãç§ãã¡ã¯å®éã«è¡ãè©°ãŸãã«è¡ããŸããïŒå å ¥è ã¯å å ¥è ã§ã¯ãããŸãã:)
ããã...
ãã¡ããå€ã«åºãããšãã§ããŸããã...
ããããæåã«ãäžè¬çãªã¢ããªã±ãŒã·ã§ã³ã³ãŒãæŽåæ§ãã§ãã¯ã®å®è£ æ¹æ³ãèŠãŠã¿ãŸãããã
ããå ·äœçã«ã¯ãæåã«ãã£ãã³ãŒããå€æŽããä¿è·ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®å®è¡äžã«äœããã®åœ¢ã§ã¡ã¢ãªå ã®å ŽæãèŠã€ããå¿ èŠããããŸãã
ã©ãã«ã¯ããã¹ãŠãã§ãã
ã»ãšãã©ã®ãã³ãžä»ããããã¯ã¿ãŒã¯ã©ãã«ã«åºã¥ããŠæ©èœããã®ã§ããªãå¥ã®èªè»¢è»ãèãåºãå¿ èŠããããŸãã ã©ãã«ãšã¯äœã§ãã-ååãšããŠãgotoïŒïŒã§äœ¿çšããã誰ããããŸãã«ãæãããŠããªãã©ãã«ã§ãããæãæ theãªäººã ããé«åºŠã«ä¿®é£Ÿããã "FI"ãè¡šçŸããŠããŸããã
ããã...ç§ãã¡ã¯ãããã«ã€ããŠã©ãæããŸããïŒ ç§ãèšã£ãããã«-ç§ãã¡ã®ã¿ã°ã¯ãã¹ãŠã§ã:)
確ãã«ã埮åŠãªéãããããŸããã©ãã«ã¯ãããã·ãŒãžã£å ã®ã³ãŒãã®å°ããªéšåãå¶åŸ¡ãããšãã«äœ¿çšãããšäŸ¿å©ã§ãïŒã¯ãã¹ãã§ãã¯ã®ããã«-åŸã§ïŒãåèšã§ããã€ãã®ããã·ãŒãžã£ã«èå³ããããŸãã
ãã®ãããã©ãã«ã¯æ©èœããŸããããå®å šæ§ãã§ãã¯ã³ãŒãããã¢ãã¬ã¹ãååŸã§ããã©ãã«ãšããŠã®ç©ºã®ããã·ãŒãžã£ã¯æ©èœããŸãã
ããŠãããŒãã«ã¯æŽåæ§ãèšç®ããããã®æé å šäœãå¿ èŠã§ãããŸããïŒå®éã«ã¯äžèšã®ãã¥ã¢ã³ã¹ã®1ã€ã§ããïŒããŒã¿ãããã¯ã®CRCãæ¯èŒããç¹å®ã®å®æ°ãå¿ èŠã§ãã
ããŠãæŽèšããããã®ã¯ãããããŸãããã
const CheckedCodeValidCheckSum: DWORD = 248268; // << procedure CheckedCodeBegin; begin end; function TForm1.CalcCheckSum(Addr: Pointer; Size: Integer): DWORD; var pCursor: PByte; I: Integer; Dumee: DWORD; begin Result := 0; pCursor := Addr; for I := 0 to Size - 1 do begin if pCursor^ <> 0 then Inc(Result, pCursor^) else Dec(Result); Inc(pCursor); end; end; procedure TForm1.CheckCodeProtect; var CheckedCodeBeginAddr, CheckedCodeEndAddr: Pointer; CurrentCheckSum: DWORD; begin // CheckedCodeBeginAddr := @CheckedCodeBegin; // CheckedCodeEndAddr := @CheckedCodeEnd; // CurrentCheckSum := CalcCheckSum(CheckedCodeBeginAddr, Integer(CheckedCodeEndAddr) - Integer(CheckedCodeBeginAddr)); if CurrentCheckSum <> CheckedCodeValidCheckSum then begin MessageBox(Handle, ' .', PChar(Application.Title), MB_ICONERROR); TerminateProcess(GetCurrentProcess, 0); end; end; function TForm1.GenerateSerial(const AppUserName: string): string; const MagicSerialMask: int64 = $C5315E6121543992; var I: Integer; SN: int64; RawSN: string; begin SN := 0; Result := ''; for I := 1 to Length(AppUserName) do begin Inc(SN, Word(AppUserName[I])); SN := SN * 123456; end; Sn := SN xor MagicSerialMask; RawSN := IntToHex(SN, 16); for I := 1 to 16 do if ((I - 1) mod 4 = 0) and (I > 1) then Result := Result + '-' + RawSN[I] else Result := Result + RawSN[I]; end; procedure TForm1.btnCheckSerialClick(Sender: TObject); begin // CheckCodeProtect; if edSerial.Text <> GenerateSerial(edAppUserName.Text) then ShowMessage(' ') else begin Image1.Visible := True; Label1.Visible := False; Label2.Visible := False; Label3.Visible := False; edAppUserName.Visible := False; edSerial.Visible := False; btnCancel.Visible := False; btnCheckSerial.Visible := False; end; end; procedure CheckedCodeEnd; begin end;
ããã«ãããã®ïŒ
空ã®ããã·ãŒãžã£CheckedCodeBeginããã³CheckedCodeEndã®åœ¢åŒã®2ã€ã®ã©ãã«ãããã2ã€ã®ã©ãã«éã®ããŒã¿ã®ããã§ãã¯ãµã ãã®èšç®ã¯ãCheckCodeProtectããã·ãŒãžã£ã«ãã£ãŠå®è¡ãããŸãã
ååãšããŠãè€éãªãã®ã¯ãŸã£ãããããŸããããåæããŠã¿ãŸãããã
å®éã«ã¯ãå€ãã®çç±ïŒ
- ãã®ã³ãŒãã¯ããã£ã¹ã¯äžã®ã¢ããªã±ãŒã·ã§ã³æ¬äœã®ããããæ€åºããŸãïŒèµ·åæã«æ¢ã«ãã€ããå€æŽãããŠããããïŒã
- ãã®ã³ãŒãã¯ãããŒããŒã«ãã£ãŠã¢ããªã±ãŒã·ã§ã³æ¬äœã®ããããæ€åºããŸãïŒäžèšãåç §ïŒã
- ãããŠããã®ã³ãŒãã¯...æåŸã®èšäºã®åçãèŠããŠããŸããïŒ
ã¯ããã¯ããããã¯ãããã¬ãŒã«ãã£ãŠã€ã³ã¹ããŒã«ããããã¬ãŒã¯ãã€ã³ãã§ãã ãŸããBPã®ã€ã³ã¹ããŒã«ã¡ã«ããºã ã¯ã¢ããªã±ãŒã·ã§ã³æ¬äœã®å€æŽã«ããããã圌ã®ã³ãŒããå®å šã«æ€åºããŸãã
ããŒãããã¯ã®3çªç®ã®æ³šæç¹-BPã®æ€åºã¯ãã³ãŒãã®æ¬æããã§ãã¯ããããšã§å®è¡ãããŸãã
確ãã«ãæ®å¿µãªããšã«ãããã§ã¯ãã¹ãŠãããã»ã©åçŽã§ã¯ãããŸãããå Žåã«ãã£ãŠã¯ããã®ã³ãŒãã¯æ©èœããŸããããæ¥ããŸãããããã«å°éããŸãã
ããŠãæ²ããããšã«ãç§ãèšã£ãããã«ããã®ãã§ãã¯ã¯ç°¡åã«æ€åºãããŸãã ããšãã°ã以äžã¯ãããã¬ãŒã®äžããã®ã¹ã¯ãªãŒã³ã·ã§ããã§ãã¹ãã£ã³ã®éå§æã«ããã«äžæãããŸãã
ãã§ãã¯ãµã èšç®æé ã®ã³ãŒãã¯éã§åŒ·èª¿è¡šç€ºããããããã¬ãŒã¯ä¿è·ãããé åãèªã¿åãããšããæåã®è©Šã¿ã§ã¢ãã¬ã¹0x467069ã§äžæãããŸããã
æ£ç¢ºã«èšããšãããã§å°ãããŸãããŸããã確èªã³ãŒãããã§ãã¯å¯Ÿè±¡ã®ç¯å²å€ã«ããå Žåããã®åœä»€ã§åæ¢ããã ããªã®ã§ããã¡ããæåã®ãPUSH EBXãã§åæ¢ããŸããã
ããããããã¯æè©ã§ãã質åã¯ç°ãªããŸãããããŠä»ãäœãããŸããïŒ
ãŸããæåã«ããã¹ãŠãããã»ã©æãããã§ã¯ãããŸããã ããã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã³ãŒãã®æŽåæ§ã®åäžã®ãã§ãã¯ã®ã¿ãå®è£ ãããŠããŸãã ã¯ããç°¡åã«æ€åºãããŸãã ã¯ãããããã§ãç°¡åã«åé€ã§ããŸããããããã®ããã€ããçžäºã«å¶åŸ¡ãåãããšã劚ããã®ã¯ãªãã§ããïŒ ããããåæ§ã«åé€ãããŸããïŒ ããŠã質åã§ã¯ãããŸããããããã«è¿œå ããŸãããè²»çšã¯ãããã§ããïŒ
ä¿è·èªäœã®éçºè ããçŽæ¥ã¢ããªã±ãŒã·ã§ã³ã»ãã¥ãªãã£ã®åæã«è£œåãéãããŠããŸããïŒç³ãèš³ãããŸããããååã¯ãããŸããïŒã VMåæåã³ãŒãããã°ããèŠãŠãããã«åæã®ãã¹ãæŠèª¬ããŸãããç¹å®ã®APIé¢æ°ãåŒã³åºããšãã«ãå°ããªããŒã¿ãããã¯ã®æå·åã¢ã«ãŽãªãºã ãåŒãåºãã ãã§ããã åé¡ã¯ãã¢ããªã±ãŒã·ã§ã³ã®1ãã€ãã«ããããé©çšãããšããã«ããã§ãã¯ãµã æ€èšŒã¡ã«ããºã ãæ©èœããããšã§ããã åœç¶ãç§ã¯ããã«ãããããµããããŸããããå€æããããã«ãããµããã³ãŒãã¯4ã€ã®ç°ãªãã¢ã«ãŽãªãºã ã«ãã£ãŠå¶åŸ¡ãããŠããŸããã ç§ã¯ãããã«ããããé©çšãå§ããŸããããã©ãæããŸããïŒ åãããã«ã€ããŠãéªåŽ©ã®ããã«ã³ãŒãã®æŽåæ§ãå¶åŸ¡ããã³ãŒãããŸããŸãç解ãããŠããŸãã ãã®çµæã倧éã®æåãããã«justãããã¹ãŠã®ãã¥ã¢ã³ã¹ãèæ ®ããŠãã»ãŒ1é±éã®äœæ¥ãèŠããèªåãŠãŒãã£ãªãã£/ãããã¬ãŒãäœæããå¿ èŠããããŸããã ãããŠæåŸã«ãç§ã¯ä¿è·ã³ã¢ã®æ¬¡ã®ã¬ãã«ã«åºããããŸããã
ãã ããããã¯ãã¯ãéèŠã§ã¯ãªããæå³ãéèŠã§ããå¿ èŠã§ããã°ããã§ãã¯ãµã ã®äºçŽ°ãªæ€èšŒã§ãã£ãŠããã¯ã©ãã«ãŒã«ãŸãšããªé çãããããå¯èœæ§ããããŸãã
ããŠãä»çŸå®ã«ã
æŽåæ§ãã§ãã¯ã³ãŒããæ€åºããããã«ãã¯ã©ãã«ãŒã¯MBPã䜿çšããŸããã
ãããŠãããŒãžã«PAGE_GUARDå±æ§ãå²ãåœãŠãããšã§ãããããã©ã®ããã«æ©èœããããèŠããŠããŸãã ãããã£ãŠããããã¬ãŒã®åçãç¥ã£ãŠããã®ã§ããããé²ãããšãã§ããŸãããã®å±æ§ãåé€ããã ãã§ããããã¬ãŒãå¶åŸ¡ããã¯ãã®ã¡ã¢ãªãŒãžã®ã¢ã¯ã»ã¹ã«å¿çããªããªããŸãã
確ãã«ã埮åŠãªéãããããŸããããã¯ããããã¬ãŒãã€ã³ã¿ãŒã»ããããŠåŒã³åºããçŠæ¢ã§ãããããè匱ãªVirtualProtectãåŒã³åºãããšã§å®çŸã§ããŸãã ããããããã«ã¯éã¹ã¬ããã®ãã«ãããããŸããããšãã°ããã®èšäºã§èª¬æãããŠããããã«è¡ãããšãã§ããŸã ã
çå®ã¯ããã¢ã¢ããªã±ãŒã·ã§ã³ã§PAGE_GUARDãåé€ãããªãã·ã§ã³ãèæ ®ããªãããšã§ãã ããããå¿é ããªãã§ãã ãããå¥ã®èå³æ·±ãæ¹æ³ã玹ä»ããŸããããã«ã€ããŠã¯ãããå°ããã¥ã¢ã³ã¹ãèæ ®ããå¿ èŠãããã®ã§ãå°ãåŸã§èª¬æããŸãã
ããããã¯ãã¢ããªã±ãŒã·ã§ã³ã®æŽåæ§å¶åŸ¡ã³ãŒãã¯ããããã³ã°ãããªãããã«ïŒåçŽåããããã«ïŒæžãããŠãããšæããŸã...
ãããã¬ãŒæ€åº
ããŠãä»ãç§ãã¡ã¯çµµãšãããã¬ã®å©ããåããŠãã©ãŒã ã欲ãããšããçµè«ã«éããŸããã ãã¡ããããããæ€åºããæ¹æ³ãåŠã¶å¿ èŠããããŸãã ãšãããããIsDebuggerPresenté¢æ°ã«ã€ããŠèª¬æããŸããããããã§ååã§ãã
ã³ãŒããæžããŸãïŒ
function IsDebuggerPresent: BOOL; stdcall; external kernel32; procedure TForm1.FormCreate(Sender: TObject); begin if IsDebuggerPresent then begin MessageBox(Handle, ' .', PChar(Application.Title), MB_ICONERROR); TerminateProcess(GetCurrentProcess, 0); end; end;
ãã¹ãŠãéåžžã«åçŽã§ãããããã¬ã®äžã«ããå Žåããã®é¢æ°ã¯Trueãè¿ããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®æŽåæ§ããã§ãã¯ããããã®ã³ãŒãã¯éåžžã«è€éã§ãããããããããé©çšããããšã¯äžå¯èœã§ããããã®é¢æ°ã®åŒã³åºãã¯ä¿è·ãããé åã«é 眮ããããšæ³å®ããŠããŸãã
ãã®å Žåãã¯ã©ãã«ãŒã¯äœã«é©çšãããŸããïŒ
ã¢ããªã±ãŒã·ã§ã³æ¬äœã«ããããé©çšã§ããªããšããäºå®ãèãããšãå®éã«ã¯3ã€ã®ãªãã·ã§ã³ãããããŸããã
- BPããã®é¢æ°ã®åŒã³åºãã«é 眮ããåŒã³åºãã®çµæã眮ãæããŸãã
- åžžã«Falseãè¿ãããã«ããã®é¢æ°ã®ã³ãŒããä¿®æ£ããŸã
- ãããã°ãããããã»ã¹ã®ã¢ãã¬ã¹ç©ºéã§Peb.BeingDebuggedå€æ°ãå€æŽããŸãã
3çªç®ã®ãªãã·ã§ã³ã«å¯ŸåŠããããšã¯å°é£ã§ãïŒå¯èœã§ãããå¿ é ã§ã¯ãããŸããïŒããæåã®2ã€ããã詳现ã«æ€èšããããæ£ç¢ºã«ã¯2çªç®ã®ãªãã·ã§ã³ãæ€èšããŸãã æåã«ã0xCCãªãã³ãŒãã䜿çšããŠBPãã€ã³ã¹ããŒã«ãããšãã«ãã¢ããªã±ãŒã·ã§ã³ã³ãŒãããããçæãããŸãã
æåã«ããããã°ãããã¢ããªã±ãŒã·ã§ã³ã®ãã®ã³ãŒããFormCreateããã·ãŒãžã£ã«è¿œå ããŸãã
procedure TForm1.FormCreate(Sender: TObject); var P: PCardinal; begin P := GetProcAddress(GetModuleHandle(kernel32), 'IsDebuggerPresent'); ShowMessage(IntToHex(P^, 8));
IsDebuggerPresenté¢æ°ã®æåã®4ãã€ãã衚瀺ãããŸãã
ãã®ãããªã³ãŒããæžãããšã¯ã§ããŸããïŒ
function IsDebuggerPresent: BOOL; stdcall; external kernel32; procedure TForm1.FormCreate(Sender: TObject); var P: PCardinal; begin P := @IsDebuggerPresent; ShowMessage(IntToHex(P^, 8));
第2ã®å®æœåœ¢æ ã§ã¯ãéçé¢æ°ã䜿çšããã¢ãã¬ã¹ã¯é¢æ°æ¬äœã®å é ãæãã®ã§ã¯ãªããJMP圢åŒã®ã¢ããã¿ãŒãããã€ã³ããŒãããŒãã«ãæããŸãã
ã³ãŒããå®è¡ããŠãå€ãæãåºããŸãããã
åã·ã¹ãã ã®äžã§ã¯ç°ãªããŸããããšãã°ãXPã§ã¯å ã®é¢æ°ã®æ¬äœã«ãªãã7ã€ã§ã¯ã«ãŒãã«ããŒã¹ã®ã¢ããã°çšã®ã¢ããã¿ãŒããããŸãã 次ã®å³ã«å¯Ÿå¿ããå€9090F3EBãååŸããŸããã
次ã«ãèšäºã®2çªç®ã®éšåãããããã¬ãŒãåãäžããŠãOnBreakPointã¡ãœããã§ãã®ã³ãŒãã䜿çšããŠãã®é¢æ°ã®æ¬äœã«ããããé©çšããŸãã
procedure TTestDebugger.HideDebugger; const PachBuff: array [0..2] of Byte = ( $31, $C0, // xor eax, eax $C3 // ret ); var Addr: Pointer; begin Addr := GetProcAddress(GetModuleHandle(kernel32), 'IsDebuggerPresent'); FCore.WriteData(Addr, @PachBuff[0], 3); end; procedure TTestDebugger.OnBreakPoint(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord; BreakPointIndex: Integer; var ReleaseBreakpoint: Boolean); var JmpOpcode: Byte; begin if ExceptionRecord.ExceptionAddress = Pointer(FCore.DebugProcessData.EntryPoint) then begin HideDebugger;
ãã¥ã¢ã³ã¹ããããŸããkernel32.dllã©ã€ãã©ãªã®ã¢ãã¬ã¹ã¯ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã§åãã§ãããããIsDebuggerPresenté¢æ°ã®ã¢ãã¬ã¹ã¯ãããã¬ãŒãšãããã°ãããã¢ããªã±ãŒã·ã§ã³ã§åãã«ãªããŸãã
ãããã®æå³ã¯ãEAXã¬ãžã¹ã¿ãç¡å¹ã«ããããšã§ããããã«ãããé¢æ°ã®çµæãè¿ããããã®é¢æ°ãåŒã³åºãã³ãŒãã«æ»ããŸãã
ãããã¬ãŒãèµ·åãããšãã¢ããªã±ãŒã·ã§ã³ãèµ·åããããã»ã¹ã¡ã¢ãªã§ã®å¹²æžã®çµæããããã¬ãŒã®FormCreateé¢æ°ã®ã³ãŒããæ€åºãããªããªããŸãã 確ãã«ããã®é¢æ°ã®æåã®4ãã€ããèªã¿åãã³ãŒãã¯ãçªå·9090F3EBã§ã¯ãªãããããã®ãªãã³ãŒãã«å¯Ÿå¿ããçªå·90C3C031ãè¿ããŸãã
ç¹å®ã®é¢æ°ã®æ¬äœã«ããããé©çšãããŠããããšãã©ã®ããã«å€æã§ããŸããïŒ ååãšããŠããã®é¢æ°ã®æåã®4ãã€ãã¯ãã£ã¹ã¯äžã«ããkernel32.dllãã¡ã€ã«ããèªã¿åãããšãã§ããŸããããã®å Žåãã©ã€ãã©ãªæ¬äœãéããšãåãããããé©çšããããã¡ã€ã«ãžã®ãã¹ã«çœ®ãæãããããã¹ãŠãæ£åžžã§ããããšã確èªãããŸãã
ããããå®éã«ã¯ãã£ãã«äœ¿çšãããªãå¥ã®æ¹æ³ããããŸãïŒééããŠããªããã°ãäžåºŠã ãäŒã£ãããšããããŸãïŒã
ãã£ã¹ã¯ããæ£ããå€ãèªã¿åãããšãã§ããªããããä»ã®ããã»ã¹ã®ã¡ã¢ãªããå¿ èŠãª4ãã€ããèªã¿åãããšã§ååŸã§ããŸãããã¡ããããã®ããã»ã¹ããããã¬ãŒã®äžã«ãããåãæ¹æ³ã§å¿ èŠãªæ©èœãã€ã³ã¿ãŒã»ããããå¯èœæ§ã¯ãããã§ãããéåžžã«å°ããã§ãã
ãã®çµæã次ã®ã³ãŒããèšè¿°ããŸãã
function IsDebuggerPresent: BOOL; stdcall; external kernel32; procedure TForm1.CheckIsDebugerPresent; var Snapshot: THandle; ProcessEntry: TProcessEntry32; ProcessHandle: THandle; pIsDebuggerPresent: PDWORD; OriginalBytes: DWORD; lpNumberOfBytesRead: DWORD; begin pIsDebuggerPresent := GetProcAddress(GetModuleHandle(kernel32), 'IsDebuggerPresent'); Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if Snapshot <> INVALID_HANDLE_VALUE then try ProcessEntry.dwSize := SizeOf(TProcessEntry32); if Process32First(Snapshot, ProcessEntry) then begin repeat if ProcessEntry.th32ProcessID = GetCurrentProcessId then Continue; ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessEntry.th32ProcessID); if ProcessHandle <> 0 then try if ReadProcessMemory(ProcessHandle, pIsDebuggerPresent, @OriginalBytes, 4, lpNumberOfBytesRead) then begin if OriginalBytes <> pIsDebuggerPresent^ then begin MessageBox(Handle, ' IsDebuggerPresent .', PChar(Application.Title), MB_ICONERROR); TerminateProcess(GetCurrentProcess, 0); end; if IsDebuggerPresent then begin MessageBox(Handle, ' .', PChar(Application.Title), MB_ICONERROR); TerminateProcess(GetCurrentProcess, 0); end; end; finally CloseHandle(ProcessHandle); end; until not Process32Next(Snapshot, ProcessEntry) end; finally CloseHandle(Snapshot); end; end; procedure TForm1.FormCreate(Sender: TObject); begin CheckIsDebugerPresent; CheckCodeProtect; end;
ããã§ã¯é ãè¯ããªããTlHelp32ã®æšæºæ©èœãå©çšããŠãããšãã°ããã»ã¹ã®ãªã¹ããååã«ååŸããŸããã
ãããã£ãŠãããŒãããã¯ã®å¥ã®ã¡ã¢-å¯èœãªéããéèŠãªAPIé¢æ°ã®æŽåæ§ãåžžã«ç¢ºèªããŸããããã¯ãæ¢ç¥ã®æ¹æ³ã§è¡ãå¿ èŠã¯ãããŸããã
ã¯ãããŸããããã«ãå¥ã®ãã¥ã¢ã³ã¹ããããŸãã7ã®äžã§ãkernel32.dllããIsDebuggerPresentãåŒã³åºããšãkernelbase.dllããåãé¢æ°ãåŒã³åºãããšã«ãªããŸãã
ãã®çµæããã¹ãŠã®å€æŽã®åŸããã®æ©èœã¯å®å šæ§ç£èŠã·ã¹ãã ã«ãã£ãããšæçšãããé¡ã«ããããããããããšã¯ãã§ã«éåžžã«åé¡ããããŸãããã®ä¿è·ãåé¿ããæ¹æ³ã«ã€ããŠã¯åŸã§èª¬æããŸãããä»åºŠã¯ä»ã®ããšãèŠãŠã¿ãŸãããã
ããã»ã¹ãžã®ãããã¬ãŒã®æ¥ç¶ãæ€åºããŸãã
ãããã¬ã®äžã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åããåã«ããããã¬ãªãã§äœãèµ·åããå¿ èŠãããããèŠãŠãã ããããããã°ã®ãã¹ãŠã®ãã§ãã¯ã«åæ ŒãããŸã§åŸ ã¡ããã®åŸãããã¬ãã¢ããªã±ãŒã·ã§ã³ã«æ¥ç¶ããŸããïŒ
ã¯ãããã®å Žåããã¹ãŠã®ã³ãŒãã¯æ©èœããŸãããããããéšåçã«ã¯æ©èœããŸãã
ãŸãã¯ããã®ãããªæããæ€åºããããã«ãããšãã°ãã¿ã€ããŒãèšå®ããCheckIsDebugerPresentããã·ãŒãžã£ãå®æçã«åŒã³åºãããšãã§ããŸãããäºå®äžãæ¥ç¶ãæ€åºããããã«ãããå¿ èŠãšããŸãããå®éã«ã¯ãDebugActiveProcessé¢æ°ããããã¬ãŒã§åŒã³åºããããšãDbgUiRemoteBreakiné¢æ°ããããã°ãããã¢ããªã±ãŒã·ã§ã³ã§åžžã«åŒã³åºãããŸãããããç¥ã£ãŠã次ã®ããªãã¯ãäžããŠãããŸãã
èªèº«ãŸãã¯DbgUiRemoteBreakiné¢æ°ã®æ¬äœã«ããããé©çšããéå§æã«TerminateProcessé¢æ°ã®ã¢ãã¬ã¹ã«é·ç§»ãè¿œå ããããããããã¬ãŒãããã»ã¹ã«æ¥ç¶ããããšããã«ããã»ã¹ãçµäºããŸãã
次ã®ã³ãŒããããã¯ãäœæããŸãã
type TDbgUiRemoteBreakinPath = packed record push0: Word; push: Byte; CurrProc: DWORD; moveax: byte; TerminateProcAddr: DWORD; calleax: Word; end; procedure TForm1.BlockDebugActiveProcess; var pDbgUiRemoteBreakin: Pointer; Path: TDbgUiRemoteBreakinPath; OldProtect: DWORD; begin pDbgUiRemoteBreakin := GetProcAddress(GetModuleHandle('ntdll.dll'), 'DbgUiRemoteBreakin'); if pDbgUiRemoteBreakin = nil then Exit; Path.push0 := $006A; Path.push := $68; Path.CurrProc := $FFFFFFFF; Path.moveax := $B8; Path.TerminateProcAddr := DWORD(GetProcAddress(GetModuleHandle(kernel32), 'TerminateProcess')); Path.calleax := $D0FF; if VirtualProtect(pDbgUiRemoteBreakin, SizeOf(TDbgUiRemoteBreakinPath), PAGE_READWRITE, OldProtect) then try Move(Path, pDbgUiRemoteBreakin^, SizeOf(TDbgUiRemoteBreakinPath)); finally VirtualProtect(pDbgUiRemoteBreakin, SizeOf(TDbgUiRemoteBreakinPath), OldProtect, OldProtect); end; end; procedure TForm1.FormCreate(Sender: TObject); begin BlockDebugActiveProcess; CheckIsDebugerPresent; CheckCodeProtect; end;
ãã®ãããªãããã®çµæãšããŠã次ã®ã³ãŒããDbgUiRemoteBreakiné¢æ°ã®å é ã«é 眮ãããŸãïŒ
ã€ãŸããTerminateProcessé¢æ°ã«å¿ èŠãªããã2ã€ã®ãã©ã¡ãŒã¿ãŒã倧ãŸãã«ã¹ã¿ãã¯ã«é 眮ãããŸãïŒéã®é åºã§ç§»åããŸãïŒãçŸåšã®ããã»ã¹ããã®åŸãEAXã¬ãžã¹ã¿ã¯TerminateProcessé¢æ°ã®ã¢ãã¬ã¹ã§åæåãããåŒã³åºãããŸãã
èšäºã®2çªç®ã®éšåãããããã¬ãŒã䜿çšããŠããã»ã¹ã«åå ããããšãããšãCREATE_PROCESS_DEBUG_EVENTã€ãã³ãã®å°çã®ã¿ã衚瀺ãããŸããããã®ã€ãã³ãã®å°çæã§ãããããã°ãããããã»ã¹ã§ã¯äœãã§ããŸãããããšãã°ãBPã®ã€ã³ã¹ããŒã«ã¯å€±æããŸãããªã©
ã»ãšãã©ã®ãããã¬ãŒã§ã¯ãããã§ååã§ãã
æ®å¿µãªãããããã¯è£ ç²è²«éãªãã·ã§ã³ã§ã¯ãããŸãããDebugActiveProcessãåŒã³åºãåã«å ã®ã³ãŒããè¿ãããšã§ãã¢ããªã±ãŒã·ã§ã³ã®æ¬äœã«ããããé©çšããããšã劚ãããã®ã¯äœããªãããã§ããïŒç¢ºãã«ãç§ã¯ãããèŠãããšããªãããããã§ã...ïŒ
ã¡ã¢ãªãã¬ãŒã¯ãã€ã³ããã€ãã¹
æ¢ã«è¿°ã¹ãããã«ãPAGE_GUARDããŒãžã®ã»ãã¥ãªãã£å±æ§ã確èªããããšã«ãããMBPã®ååšãå€æã§ããŸããããã¯ãVirtualQueryé¢æ°ãåŒã³åºãããšã§å®è¡ã§ããŸãããŸãã¯ãVirtualProtectãåŒã³åºããŠå±æ§ãç°¡åã«åå²ãåœãŠã§ããŸãã
ããããå¥ã®ããªãããŒãªæ¹æ³ããããããã¯ReadProcessMemoryãšåŒã°ããŸããããã¯ããããã¬ãŒã§ãããã°ãããããã»ã¹ããããŒã¿ãèªã¿åãã®ãšåãé¢æ°ã§ãããã®ãã¥ã¢ã³ã¹ã¯æ¬¡ã®ãšããã§ããPAGE_GUARDãã©ã°ã§ä¿è·ãããããŒãžããããŒã¿ãèªã¿åãããšãããšã察å¿ããããŒãžã®ããŒã¿ãããã¯ã¯ãŒãã§åãããããããã¬ãŒã§ã¯EXCEPTION_GUARD_PAGEã€ãã³ããçºçããŸãããããããå°åã®ãµã€ã¬ã³ããã§ãã¯ãã§ããã¢ããªã±ãŒã·ã§ã³ã³ãŒãã®æŽåæ§ããã§ãã¯ãããšãã«äœ¿çšããMVRãã€ã³ã¹ããŒã«ãããŠããå ŽåãããŒã¿ã¯æ£ãããšèŠãªãããããã®çµæããã§ãã¯ãµã ã¯æåŸ ããããã®ãšåæããŸãããããã«ãèšé²ãå¶åŸ¡ããããŒããŠã§ã¢ãã¬ãŒã¯ãã€ã³ãããã®é¢æ°ã®èªã¿åãå ã®ã¢ãã¬ã¹ã«èšå®ãããŠããå Žåãèªã¿åã/æžã蟌ã¿ãããã¬ãŒã¯ãã®æäœã«é¢ããéç¥ãåä¿¡ããŸããã
ãããã£ãŠãCalcCheckSumé¢æ°ã次ã®ããã«æžãæããŸãã
function TForm1.CalcCheckSum(Addr: Pointer; Size: Integer): DWORD; var pRealData, pCursor: PByte; I: Integer; Dumee: DWORD; begin pRealData := GetMemory(Size); try ReadProcessMemory(GetCurrentProcess, Addr, pRealData, Size, Dumee); Result := 0; pCursor := pRealData; for I := 0 to Size - 1 do begin if pCursor^ <> 0 then Inc(Result, pCursor^) else Dec(Result); Inc(pCursor); end; finally FreeMemory(pRealData); end; end;
ãã®ããã«ã1ã€ã®æ©èœã§ãBPãå åçãããã«ã¯NVRãããé²åŸ¡ããŸãã
ãããåé¿ããæ¹æ³ã¯ïŒ
ããŠãã¢ããªã±ãŒã·ã§ã³ä¿è·ã³ãŒãã¯ããè€éã«ãªããŸããããã®æ å ±ã§ååã§ãã
èšäºã®æåŸã§ããã€ãã®ãã¥ã¢ã³ã¹ã«ã€ããŠèª¬æããŸãããå®å šæ§æ€èšŒã³ãŒããäžå¯è§£ãšèŠãªãããšã«åæããç¬éãèæ ®ããŠããããã¬ãŒã«åºã¥ããŠããŒããŒãäœæããããšããŸãããããã£ãŠãæ€èšŒæ¬äœã«ããããé©çšããŸããã
ã¯ã€ã€ãŒãã¬ãŒã ãäœæããŠããŸããéå§ãšåæ¢ã¯æ¬¡ã®ããã«ãªããŸãã
constructor TTestDebugger.Create(const Path: string); begin FCore := TFWDebugerCore.Create; if not FCore.DebugNewProcess(Path, True) then RaiseLastOSError; FCore.OnCreateProcess := OnCreateProcess; FCore.OnLoadDll := OnLoadDll; FCore.OnDebugString := OnDebugString; FCore.OnBreakPoint := OnBreakPoint; FCore.OnHardwareBreakpoint := OnHardwareBreakpoint; FCore.OnUnknownBreakPoint := OnUnknownBreakPoint; FCore.OnUnknownException := OnUnknownException; end; destructor TTestDebugger.Destroy; begin FCore.Free; inherited; end;
ç§ã¯äºæ¬¡ãã³ãã©ãŒãã¹ãããããŸãããããã¯äŸã®ãœãŒã¹ã³ãŒãã§èŠãããšãã§ããŸããååãšããŠãæ°ãããã®ã¯äœããããŸããããã¹ãŠã¯èšäºã®æåŸã®éšåã§ãã§ã«èª¬æãããŠããŸãã
æåã®ã¿ã¹ã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ã«ãããããã¬ãŒã®æ€åºãç¡å¹ã«ããããšã§ããã¢ããªã±ãŒã·ã§ã³ã¯IsDebuggerPresentã®æŽåæ§ããã§ãã¯ããïŒã¿ã¹ã¯ã«åŸã£ãŠïŒãã§ãã¯ã«ããããé©çšã§ããªããããPeb.BeingDebuggedãã©ã¡ãŒã¿ãŒã®å€ãå€æŽãããªãã·ã§ã³ã1ã€ãããããŸããã
次ã®ã³ãŒãã§ããããã£ãŠã¿ãŸãããïŒ
procedure TTestDebugger.HideDebugger(hProcess: THandle); var pProcBasicInfo: PROCESS_BASIC_INFORMATION; pPeb: PEB; ReturnLength: DWORD; begin if NtQueryInformationProcess(hProcess, 0, @pProcBasicInfo, SizeOf(PROCESS_BASIC_INFORMATION), @ReturnLength) <> STATUS_SUCCESS then RaiseLastOSError; if not ReadProcessMemory(hProcess, pProcBasicInfo.PebBaseAddress, @pPeb, SizeOf(PEB), ReturnLength) then RaiseLastOSError; pPeb.BeingDebugged := False; if not WriteProcessMemory(hProcess, pProcBasicInfo.PebBaseAddress, @pPeb, SizeOf(PEB), ReturnLength) then RaiseLastOSError; end;
ããã§ã¯ãã¹ãŠãç°¡åã§ããããã»ã¹ç°å¢ãããã¯ã®ã¢ãã¬ã¹ãååŸããBeingDebuggedãã©ã¡ãŒã¿ãŒãå€æŽããŠããã¹ãŠãæžãæ»ããŸãããããã£ãŠãIsDebuggerPresenté¢æ°ã¯ãããã¬ãŒãžã®å¿çãåæ¢ããŸãã䜿çšãããæ§é äœã®å®£èšã¯ããã¢ãœãŒã¹ã«ãããŸãã
æåã®æ®µéãä»åºŠã¯2çªç®ã®æ®µéãå®äºããŸããã誀ã£ãŠå ¥åãããã³ãŒãã«ã¢ããªã±ãŒã·ã§ã³ãå¿çããªãããã«ããã©ã®ãããªå Žåã§ãç»åã衚瀺ããå¿ èŠããããŸãã
ãããè¡ããŸãïŒ
ãããããããã¬ã§å€æ°ã®å€ãè€æ°åå€æŽããŠããå¯èœæ§ããããŸãïŒããã«ã€ããŠã¯ãèšäºã®æåã®éšåã§èª¬æããŸããïŒãããã§ãåæ§ã®ããšãè¡ããŸããããªããèŠããŠããããã«ãJEåœä»€ã¯ç»åã衚瀺ãã責任ããããŸããç²ãå ŽåãããŒã«å€æ°ãšå€if..elseã®æ¡ä»¶ããããšæ³åããŠãã ãããããã§ãªããã°ããã®ãããªæ¡ä»¶ã§äžæãããšãã³ãŒãã®å®è¡æ¡ä»¶ãå¶åŸ¡ã§ããŸããå€å€æ°ã®å€æŽã«ãã£ãŠãæ£ç¢ºã«äœãå®è¡ãã¹ããã瀺ããŸãïŒthenãŸãã¯elseãããã¯ã
JEãªãã¬ãŒã¿ãŒã¯ããã®ãããªããŒã«å€æ°ã«åºã¥ããŠé·ç§»ã決å®ããŸãããZFãã©ã°ã®åœ¢åŒã§è¡šç€ºãããŸãããã©ã°ãæå¹ãªå Žåãæ°ããã¢ãã¬ã¹ãžã®ãžã£ã³ããçºçããŸãããããã£ãŠããã®ãã©ã°ã®å€ãå¿ èŠãªå€ã«å€æŽã§ããããã«ãJEåœä»€ã§ã¢ããªã±ãŒã·ã§ã³ãäžæããããšãã¿ã¹ã¯ã§ãã
ãããè¡ãã«ã¯ãHBPãJEåœä»€ã®ã¢ãã¬ã¹ã«èšå®ããŸããããã¯ãå®å šãªã¢ããªã±ãŒã·ã§ã³ãå¶åŸ¡ã§ããªãå¯äžã®ãã®ã§ãããã®ã¢ãã¬ã¹ãèŠã€ããæ¹æ³ç§ã¯æ¬ å ŽããŸãããã®äŸã§ã¯ãã¢ãŒã«ã€ãã«ã¯crackme.exeå®è¡å¯èœãã¡ã€ã«ãå«ãŸããŠããŸããç¹ã«ãåã³ã³ãã€ã«ã®ãã³ã«ãã€ã«ã«ã®ããŒãžã§ã³ãªã©ã«ãã£ãŠãã®ã¢ãã¬ã¹ãç°ãªããããã¢ãŒã«ã€ãã«ç¹å¥ã«é 眮ããŸããã³ã³ãã€ã«ãããå®è¡å¯èœãã¡ã€ã«ã§ã¯ããã®ã¢ãã¬ã¹ã¯æ¢ã«èšç®ãããŠãããå€0x467840ãšçãããªã£ãŠããŸãã
ã³ãŒããæžãããšã¯æ®ã£ãŠããŸãïŒ
procedure TTestDebugger.OnBreakPoint(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord; BreakPointIndex: Integer; var ReleaseBreakpoint: Boolean); begin if ExceptionRecord.ExceptionAddress = Pointer(FCore.DebugProcessData.EntryPoint) then begin Writeln; Writeln(Format('!!! --> Process Entry Point found. Address: %p', [Pointer(FCore.DebugProcessData.EntryPoint)])); Writeln; HideDebugger(FCore.DebugProcessData.AttachedProcessHandle); FCore.SetHardwareBreakpoint(ThreadIndex, Pointer($467840), hsByte, hmExecute, 0, 'wait JE'); end else begin Writeln; Writeln(Format('!!! --> BreakPoint at addr 0X%p - "%s"', [ExceptionRecord.ExceptionAddress, FCore.BreakpointItem(BreakPointIndex).Description])); Writeln; end; end;
ãã®åŸãHBPã§å²ã蟌ã¿ãåŠçããæ£ãããã©ã°å€ãèšå®ããå¿ èŠããããŸãã
procedure TTestDebugger.OnHardwareBreakPoint(Sender: TObject; ThreadIndex: Integer; ExceptionRecord: Windows.TExceptionRecord; BreakPointIndex: THWBPIndex; var ReleaseBreakpoint: Boolean); var ThreadData: TThreadData; begin Writeln; ThreadData := FCore.GetThreadData(ThreadIndex); Writeln(Format('!!! --> Hardware BreakPoint at addr 0X%p - "%s"', [ExceptionRecord.ExceptionAddress, ThreadData.Breakpoint.Description[BreakPointIndex]])); FCore.SetFlag(ThreadIndex, EFLAGS_ZF, True); Writeln; end;
ããŠãããã§ãã¹ãŠã§ããå®è¡ããŠãå·Šã®å€ãå ¥åããŠãåçã楜ããã§ãã ããã
çµæã¯æ¬¡ã®ããã«ãªããŸãïŒ
ããã§éåžžã¯èµ·ãããŸãããããªãã¯ããªããé§ã貫éããä¿è·ãæžãããšæããŸãããããŠãããèã«ããããšããã¡ãããå¿ ãããããã§ã¯ãããŸããããããã¯èµ·ãããŸã:)
ããŒããŠã§ã¢ãã¬ãŒã¯ãã€ã³ãã®æ€åºïŒ
ä¿è·ãããã¢ããªã±ãŒã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯å ã§NVRãæ€åºããããšãæå³çã«åæ¢ããŸããã§ããããã®ãããªãã§ãã¯ãããå Žåãããªãè€éãªãã€ãã¹ã³ãŒããèšè¿°ããå¿ èŠãããããã§ãããããŠäžè¬çã«ã¯ããã¡ããããããã®ååšã確èªããããšããå§ãããŸãããããã£ãŠããããã¬ãŒãéããŠéåžžã®åäœãå¯èœã«ãªããŸãã
HBPã®ååšã®æ€åºã¯éåžžã«ç°¡åã§ããåãGetThreadContextãä»ããŠå®è£ ããDR7ã¬ãžã¹ã¿ããã§ãã¯ããïŒç©ºã§ãªãå ŽåãHBPãç«ã£ãŠããïŒããAPIé¢æ°åŒã³åºãã«ãã£ãŠã€ã³ã¿ãŒã»ãããããªãããã«ãäŸå€ãã¹ããŒããŠã¹ã¬ããã³ã³ããã¹ããååŸã§ããŸãã
ãããæåã®ãªãã·ã§ã³ã§ã
procedure TForm1.CheckHardwareBreakPoint; var Context: TContext; begin Context.ContextFlags := CONTEXT_DEBUG_REGISTERS; GetThreadContext(GetCurrentThread, Context); if Context.Dr7 <> 0 then begin MessageBox(Handle, ' HardwareBreaakPoint.', PChar(Application.Title), MB_ICONERROR); TerminateProcess(GetCurrentProcess, 0); end; end;
2çªç®ã®ãªãã·ã§ã³ã§ã¯ããããã°äŸå€ãçºçãã_except_handlerãã³ãã©ãŒã®ã¹ã¬ããã³ã³ããã¹ãã«é¢ããæ å ±ãåé€ãããŸãã
type // TSeh = packed record Esp, Ebp, SafeEip: DWORD; end; var seh: TSeh; function _except_handler(ExceptionRecord: PExceptionRecord; EstablisherFrame: Pointer; Context: PContext; DispatcherContext: Pointer): DWORD; cdecl; const ExceptionContinueExecution = 0; begin if Context^.Dr7 <> 0 then begin MessageBox(0, ' HardwareBreaakPoint.', PChar(Application.Title), MB_ICONERROR); TerminateProcess(GetCurrentProcess, 0); end; // Context^.Eip := seh.SafeEip; Context^.Esp := seh.Esp; Context^.Ebp := seh.Ebp; // Result := ExceptionContinueExecution; end; procedure TForm1.CheckHardwareBreakPoint2; asm // SEH push offset _except_handler xor eax, eax push fs:[eax] mov fs:[eax], esp // lea eax, seh mov [eax], esp add eax, 4 mov [eax], ebp add eax, 4 lea ecx, @done mov [eax], ecx // mov eax, [0] @done: // SEH xor eax, eax pop fs:[eax] add esp, 4 end;
ãšããã§ãèå³æ·±ãç¹ãäŸå€ãã³ãã©ã«éãããæ å ±ã®éã«æ³šæããŠãã ããããã®ãã¹ãŠã®æ å ±ã¯äŸå€ãã³ãã©ã§ã¯å©çšã§ããªããããSEHã®çãã©ãããŒãé€ããŠtry..finally..exceptãåŒã³åºãããšããããããŸãã
èŠçŽãã
ãããã¬ãŒã«å¯ŸåŠããããã€ãã®æ¹æ³ãç¥ã£ãŠããŸããããããã«å¯Ÿæããæ¹æ³ã¯ããã£ãŠããŸãããçµè«ãåºãããã®èšäºããããŸãã
äŸä»ãã®ãœãŒã¹ã³ãŒãã¯ã次ã®ãªã³ã¯ããååŸã§ããŸããhttp ïŒ//rouse.drkb.ru/blog/dbg_part3.zip
ããã§ãç§ã®ã¿ã¹ã¯ãå®äºã§ããŸãã
ãããã¬ã«ã€ããŠäŒãããã£ãããšã¯ãã¹ãŠãç§ã¯èšããŸãããåœåã¯ããã£ã1ã€ã®èšäºãèšç»ãããŠããŸããããæçµçã«ã¯ã©ãã ãã®è³æãäœæãããããããããŸã
ã
©AlexanderïŒRouse_ïŒBagel
Moscowã2012幎11æ