diff --git a/05_reversing/dynamic/setfunction_patching.md b/05_reversing/dynamic/setfunction_patching.md index 3e34e06..50f70ff 100644 --- a/05_reversing/dynamic/setfunction_patching.md +++ b/05_reversing/dynamic/setfunction_patching.md @@ -53,7 +53,7 @@ APTR SetFunction(struct Library *library, LONG funcOffset, APTR newFunction); ; Example: hook dos.library Write() at LVO -48 MOVEA.L _SysBase, A6 - JSR (-120,A6) ; Forbid() — prevent preemption during patch + JSR (-132,A6) ; Forbid() — prevent preemption during patch MOVEA.L _DOSBase, A1 MOVE.L #-48, A0 ; LVO for Write @@ -61,7 +61,7 @@ APTR SetFunction(struct Library *library, LONG funcOffset, APTR newFunction); JSR (-420,A6) ; SetFunction(DOSBase, -48, &my_write) MOVE.L D0, _orig_write ; save original function pointer - JSR (-126,A6) ; Permit() + JSR (-138,A6) ; Permit() ``` ### C equivalent: diff --git a/05_reversing/static/api_call_identification.md b/05_reversing/static/api_call_identification.md index eb39040..00de988 100644 --- a/05_reversing/static/api_call_identification.md +++ b/05_reversing/static/api_call_identification.md @@ -216,45 +216,49 @@ So immediately before the JSR: | −48 | 48 | `Write` | D1=handle, D2=buf, D3=len | D0=actual | | −54 | 54 | `Input` | — | D0=stdin handle | | −60 | 60 | `Output` | — | D0=stdout handle | -| −66 | 66 | `IoErr` | — | D0=last error code | -| −78 | 78 | `CreateDir` | D1=name | D0=lock | -| −84 | 84 | `CurrentDir` | D1=lock | D0=old lock | -| −90 | 90 | `Lock` | D1=name, D2=mode | D0=lock | -| −96 | 96 | `UnLock` | D1=lock | — | -| −102 | 102 | `DupLock` | D1=lock | D0=new lock | -| −108 | 108 | `Examine` | D1=lock, D2=fib | D0=bool | -| −120 | 120 | `ExNext` | D1=lock, D2=fib | D0=bool | -| −126 | 126 | `Info` | D1=lock, D2=infoblock | D0=bool | -| −132 | 132 | `Execute` | D1=string, D2=input, D3=output | D0=bool | -| −138 | 138 | `Delay` | D1=ticks | — | -| −144 | 144 | `DateStamp` | D1=datestamp | D0=datestamp | -| −150 | 150 | `Exit` | D1=returnCode | — | -| −156 | 156 | `LoadSeg` | D1=name | D0=seglist | -| −162 | 162 | `UnLoadSeg` | D1=seglist | — | +| −66 | 66 | `Seek` | D1=file, D2=pos, D3=mode | D0=old pos | +| −72 | 72 | `DeleteFile` | D1=name | D0=bool | +| −78 | 78 | `Rename` | D1=old, D2=new | D0=bool | +| −84 | 84 | `Lock` | D1=name, D2=mode | D0=lock | +| −90 | 90 | `UnLock` | D1=lock | — | +| −96 | 96 | `DupLock` | D1=lock | D0=new lock | +| −102 | 102 | `Examine` | D1=lock, D2=fib | D0=bool | +| −108 | 108 | `ExNext` | D1=lock, D2=fib | D0=bool | +| −114 | 114 | `Info` | D1=lock, D2=infoblock | D0=bool | +| −120 | 120 | `CreateDir` | D1=name | D0=lock | +| −126 | 126 | `CurrentDir` | D1=lock | D0=old lock | +| −132 | 132 | `IoErr` | — | D0=last error code | +| −138 | 138 | `CreateProc` | D1=name, D2=pri, D3=seglist, D4=stack | D0=port | +| −144 | 144 | `Exit` | D1=returnCode | — | +| −150 | 150 | `LoadSeg` | D1=name | D0=seglist | +| −156 | 156 | `UnLoadSeg` | D1=seglist | — | +| −192 | 192 | `DateStamp` | D1=datestamp | D0=datestamp | +| −198 | 198 | `Delay` | D1=ticks | — | +| −222 | 222 | `Execute` | D1=string, D2=input, D3=output | D0=bool | ## Quick LVO Reference: exec.library (selected) | LVO | Bias | Function | Args | Return | |---|---|---|---|---| -| −6 | 6 | `Supervisor` | A5=func | — | -| −120 | 120 | `Forbid` | — | — | -| −126 | 126 | `Permit` | — | — | -| −132 | 132 | `Disable` | — | — | -| −138 | 138 | `Enable` | — | — | -| −168 | 168 | `FindTask` | A1=name | D0=task | -| −174 | 174 | `SetTaskPri` | A1=task, D0=pri | D0=old | -| −192 | 192 | `Signal` | A1=task, D0=signals | — | +| −30 | 30 | `Supervisor` | A5=func | — | +| −120 | 120 | `Disable` | — | — | +| −126 | 126 | `Enable` | — | — | +| −132 | 132 | `Forbid` | — | — | +| −138 | 138 | `Permit` | — | — | | −198 | 198 | `AllocMem` | D0=size, D1=attrs | D0=ptr | | −210 | 210 | `FreeMem` | A1=ptr, D0=size | — | -| −234 | 234 | `Wait` | D0=signals | D0=set | -| −270 | 270 | `AddPort` | A1=port | — | | −276 | 276 | `FindName` | A0=list, A1=name | D0=node | -| −378 | 378 | `PutMsg` | A0=port, A1=msg | — | -| −384 | 384 | `GetMsg` | A0=port | D0=msg | -| −408 | 408 | `WaitPort` | A0=port | D0=msg | +| −294 | 294 | `FindTask` | A1=name | D0=task | +| −300 | 300 | `SetTaskPri` | A1=task, D0=pri | D0=old | +| −318 | 318 | `Wait` | D0=signals | D0=set | +| −324 | 324 | `Signal` | A1=task, D0=signals | — | +| −354 | 354 | `AddPort` | A1=port | — | +| −366 | 366 | `PutMsg` | A0=port, A1=msg | — | +| −372 | 372 | `GetMsg` | A0=port | D0=msg | +| −384 | 384 | `WaitPort` | A0=port | D0=msg | +| −414 | 414 | `CloseLibrary` | A1=lib | — | | −420 | 420 | `SetFunction` | A1=lib, A0=lvo, D0=func | D0=old | | −552 | 552 | `OpenLibrary` | A1=name, D0=ver | D0=base | -| −558 | 558 | `CloseLibrary` | A1=lib | — | Full tables: [[lvo_table.md](../../04_linking_and_libraries/lvo_table.md)](../../../04_linking_and_libraries/lvo_table.md) @@ -267,16 +271,17 @@ Full tables: [[lvo_table.md](../../04_linking_and_libraries/lvo_table.md)](../.. import idaapi, idc, idautils DOS_LVO = { - -30: "Open", -36: "Close", -42: "Read", -48: "Write", - -54: "Input", -60: "Output", -66: "IoErr", -132: "Execute", - -138: "Delay", -156: "LoadSeg",-162: "UnLoadSeg", + -30: "Open", -36: "Close", -42: "Read", -48: "Write", + -54: "Input", -60: "Output", -66: "Seek", -132: "IoErr", + -138: "CreateProc", -150: "LoadSeg", -156: "UnLoadSeg", + -198: "Delay", -222: "Execute", } EXEC_LVO = { - -120: "Forbid", -126: "Permit", -132: "Disable", -138: "Enable", - -198: "AllocMem", -210: "FreeMem",-234: "Wait", - -378: "PutMsg", -384: "GetMsg", -408: "WaitPort", - -420: "SetFunction", -552: "OpenLibrary", -558: "CloseLibrary", + -120: "Disable", -126: "Enable", -132: "Forbid", -138: "Permit", + -198: "AllocMem",-210: "FreeMem", -318: "Wait", + -366: "PutMsg", -372: "GetMsg", -378: "ReplyMsg", -384: "WaitPort", + -414: "CloseLibrary", -420: "SetFunction", -552: "OpenLibrary", } def apply_lvos(lib_global_name, lvo_map): @@ -369,17 +374,17 @@ elif get_name(global_ptr) == "_GfxBase": MOVEA.L 4.W, A6 ; exec base — but this is never used MOVEA.L (_DOSBase).L, A6 ; A6 overwritten with DOS base JSR (-552,A6) ; WRONG assumption: this is NOT exec OpenLibrary - ; Correct: LVO -552 for dos.library is ExAll + ; Correct: LVO -552 for dos.library is MaxCli ``` -**Why it fails:** The disassembler shows `JSR (-552,A6)` and annotates it as `exec.library OpenLibrary()` because that's the most common match. But A6 was reloaded with `_DOSBase` — the actual call is `dos.library ExAll()` at LVO `-552`. Same LVO, different library, completely different behavior. +**Why it fails:** The disassembler shows `JSR (-552,A6)` and annotates it as `exec.library OpenLibrary()` because that's the most common match. But A6 was reloaded with `_DOSBase` — the actual call is `dos.library MaxCli()` at LVO `-552`. Same LVO, different library, completely different behavior. **Correct:** Track A6's value at every `JSR`. Never assume A6 is static across a function. ```asm MOVEA.L 4.W, A6 ; A6 = SysBase (verified: exec at $4) MOVEA.L (_DOSBase).L, A6 ; A6 = DOSBase (verified: global labeled) -JSR (-552,A6) ; LVO -552 in dos.library = ExAll +JSR (-552,A6) ; LVO -552 in dos.library = MaxCli ``` ### 3. \"The Stale Base\" @@ -393,7 +398,7 @@ if (result) DOSBase->DoSometime(); // DOSBase is now stale — crash or call into freed memory ``` -In disassembly, you see `JSR (-N,A6)` after a `JSR (-558,A6)` (CloseLibrary). A6 becomes a dangling pointer. Any subsequent call through it hits freed memory — a crash or, worse, silent corruption. +In disassembly, you see `JSR (-N,A6)` after a `JSR (-414,A6)` (CloseLibrary). A6 becomes a dangling pointer. Any subsequent call through it hits freed memory — a crash or, worse, silent corruption. **Correct:** After `CloseLibrary`, zero the base pointer. In the disassembly, flag any `JSR` that follows a `CloseLibrary` sequence as suspicious. @@ -457,9 +462,9 @@ To identify every file open/read/write/close in a binary: ### Trace an Unknown Message Flow -1. Find `JSR (-378,A6)` (exec PutMsg) — identifies message senders -2. Find `JSR (-384,A6)` (exec GetMsg) — identifies message receivers -3. Find `JSR (-408,A6)` (exec WaitPort) — identifies blocking receivers +1. Find `JSR (-366,A6)` (exec PutMsg) — identifies message senders +2. Find `JSR (-372,A6)` (exec GetMsg) — identifies message receivers +3. Find `JSR (-384,A6)` (exec WaitPort) — identifies blocking receivers 4. Trace `A0` before each `PutMsg` to identify **which port** the message targets 5. Trace `A0` before each `GetMsg` to identify **which port** the receiver listens on 6. If sender and receiver port names match, you've found a communication pair diff --git a/14_references/dos_lvo_table.md b/14_references/dos_lvo_table.md index b82b758..ab9aa1c 100644 --- a/14_references/dos_lvo_table.md +++ b/14_references/dos_lvo_table.md @@ -28,139 +28,142 @@ | −144 | 144 | Exit | | −150 | 150 | LoadSeg | | −156 | 156 | UnLoadSeg | -| −162 | 162 | DeviceProc (private) | -| −168 | 168 | SetComment | -| −174 | 174 | SetProtection | -| −180 | 180 | DateStamp | -| −186 | 186 | Delay | -| −192 | 192 | WaitForChar | -| −198 | 198 | ParentDir | -| −204 | 204 | IsInteractive | -| −210 | 210 | Execute | -| −216 | 216 | AllocDosObject | -| −222 | 222 | FreeDosObject | -| −228 | 228 | DoPkt | -| −234 | 234 | SendPkt | -| −240 | 240 | WaitPkt | -| −246 | 246 | ReplyPkt | -| −252 | 252 | AbortPkt | -| −258 | 258 | LockRecord | -| −264 | 264 | LockRecords | -| −270 | 270 | UnLockRecord | -| −276 | 276 | UnLockRecords | -| −282 | 282 | SelectInput | -| −288 | 288 | SelectOutput | -| −294 | 294 | FGetC | -| −300 | 300 | FPutC | -| −306 | 306 | UnGetC | -| −312 | 312 | FRead | -| −318 | 318 | FWrite | -| −324 | 324 | FGets | -| −330 | 330 | FPuts | -| −336 | 336 | VFWritef | -| −342 | 342 | VFPrintf | -| −348 | 348 | Flush | -| −354 | 354 | SetVBuf | -| −360 | 360 | DupLockFromFH | -| −366 | 366 | OpenFromLock | -| −372 | 372 | ParentOfFH | -| −378 | 378 | ExamineFH | -| −384 | 384 | SetFileDate | -| −390 | 390 | NameFromLock | -| −396 | 396 | NameFromFH | -| −402 | 402 | SplitName | -| −408 | 408 | SameLock | -| −414 | 414 | SetMode | -| −420 | 420 | ExAll | -| −426 | 426 | ReadLink | -| −432 | 432 | MakeLink | -| −438 | 438 | ChangeMode | -| −444 | 444 | SetFileSize | -| −450 | 450 | SetIoErr | -| −456 | 456 | Fault | -| −462 | 462 | PrintFault | -| −468 | 468 | ErrorReport | -| −474 | 474 | Cli (private) | -| −480 | 480 | CreateNewProc | -| −486 | 486 | RunCommand | -| −492 | 492 | GetConsoleTask | -| −498 | 498 | SetConsoleTask | -| −504 | 504 | GetFileSysTask | -| −510 | 510 | SetFileSysTask | -| −516 | 516 | GetArgStr | -| −522 | 522 | SetArgStr | -| −528 | 528 | FindCliProc | -| −534 | 534 | MaxCli | -| −540 | 540 | SetCurrentDirName | -| −546 | 546 | GetCurrentDirName | -| −552 | 552 | SetProgramName | -| −558 | 558 | GetProgramName | -| −564 | 564 | SetPrompt | -| −570 | 570 | GetPrompt | -| −576 | 576 | SetProgramDir | -| −582 | 582 | GetProgramDir | -| −588 | 588 | SystemTagList | -| −594 | 594 | AssignLock | -| −600 | 600 | AssignLate | -| −606 | 606 | AssignPath | -| −612 | 612 | AssignAdd | -| −618 | 618 | RemAssignList | -| −624 | 624 | GetDeviceProc | -| −630 | 630 | FreeDeviceProc | -| −636 | 636 | LockDosList | -| −642 | 642 | UnLockDosList | -| −648 | 648 | AttemptLockDosList | -| −654 | 654 | RenameDosEntry | -| −660 | 660 | AddDosEntry | -| −666 | 666 | RemDosEntry | -| −672 | 672 | FindDosEntry | -| −678 | 678 | NextDosEntry | -| −684 | 684 | MakeDosEntry | -| −690 | 690 | FreeDosEntry | -| −696 | 696 | IsFileSystem | -| −702 | 702 | Format | -| −708 | 708 | Relabel | -| −714 | 714 | Inhibit | -| −720 | 720 | AddBuffers | -| −726 | 726 | CompareDates | -| −732 | 732 | DateToStr | -| −738 | 738 | StrToDate | -| −744 | 744 | InternalLoadSeg | -| −750 | 750 | InternalUnLoadSeg | -| −756 | 756 | NewLoadSeg | -| −762 | 762 | AddSegment | -| −768 | 768 | FindSegment | -| −774 | 774 | RemSegment | -| −780 | 780 | CheckSignal | -| −786 | 786 | ReadArgs | -| −792 | 792 | FindArg | -| −798 | 798 | ReadItem | -| −804 | 804 | StrToLong | -| −810 | 810 | MatchFirst | -| −816 | 816 | MatchNext | -| −822 | 822 | MatchEnd | -| −828 | 828 | ParsePattern | -| −834 | 834 | MatchPattern | -| −840 | 840 | FreeArgs | -| −846 | 846 | FilePart | -| −852 | 852 | PathPart | -| −858 | 858 | AddPart | -| −864 | 864 | StartNotify | -| −870 | 870 | EndNotify | -| −876 | 876 | SetVar | -| −882 | 882 | GetVar | -| −888 | 888 | DeleteVar | -| −894 | 894 | FindVar | -| −900 | 900 | CliInitNewcli (private) | -| −906 | 906 | CliInitRun (private) | -| −912 | 912 | WriteChars | -| −918 | 918 | PutStr | -| −924 | 924 | VPrintf | -| −930 | 930 | ParsePatternNoCase | -| −936 | 936 | MatchPatternNoCase | -| −942 | 942 | SameDevice (private) | -| −948 | 948 | ExAllEnd | -| −954 | 954 | SetOwner | +| −162 | 162 | ClearVec (private) | +| −168 | 168 | NoReqLoadSeg (private) | +| −174 | 174 | DeviceProc | +| −180 | 180 | SetComment | +| −186 | 186 | SetProtection | +| −192 | 192 | DateStamp | +| −198 | 198 | Delay | +| −204 | 204 | WaitForChar | +| −210 | 210 | ParentDir | +| −216 | 216 | IsInteractive | +| −222 | 222 | Execute | +| −228 | 228 | AllocDosObject | +| −234 | 234 | FreeDosObject | +| −240 | 240 | DoPkt | +| −246 | 246 | SendPkt | +| −252 | 252 | WaitPkt | +| −258 | 258 | ReplyPkt | +| −264 | 264 | AbortPkt | +| −270 | 270 | LockRecord | +| −276 | 276 | LockRecords | +| −282 | 282 | UnLockRecord | +| −288 | 288 | UnLockRecords | +| −294 | 294 | SelectInput | +| −300 | 300 | SelectOutput | +| −306 | 306 | FGetC | +| −312 | 312 | FPutC | +| −318 | 318 | UnGetC | +| −324 | 324 | FRead | +| −330 | 330 | FWrite | +| −336 | 336 | FGets | +| −342 | 342 | FPuts | +| −348 | 348 | VFWritef | +| −354 | 354 | VFPrintf | +| −360 | 360 | Flush | +| −366 | 366 | SetVBuf | +| −372 | 372 | DupLockFromFH | +| −378 | 378 | OpenFromLock | +| −384 | 384 | ParentOfFH | +| −390 | 390 | ExamineFH | +| −396 | 396 | SetFileDate | +| −402 | 402 | NameFromLock | +| −408 | 408 | NameFromFH | +| −414 | 414 | SplitName | +| −420 | 420 | SameLock | +| −426 | 426 | SetMode | +| −432 | 432 | ExAll | +| −438 | 438 | ReadLink | +| −444 | 444 | MakeLink | +| −450 | 450 | ChangeMode | +| −456 | 456 | SetFileSize | +| −462 | 462 | SetIoErr | +| −468 | 468 | Fault | +| −474 | 474 | PrintFault | +| −480 | 480 | ErrorReport | +| −492 | 492 | Cli | +| −498 | 498 | CreateNewProc | +| −504 | 504 | RunCommand | +| −510 | 510 | GetConsoleTask | +| −516 | 516 | SetConsoleTask | +| −522 | 522 | GetFileSysTask | +| −528 | 528 | SetFileSysTask | +| −534 | 534 | GetArgStr | +| −540 | 540 | SetArgStr | +| −546 | 546 | FindCliProc | +| −552 | 552 | MaxCli | +| −558 | 558 | SetCurrentDirName | +| −564 | 564 | GetCurrentDirName | +| −570 | 570 | SetProgramName | +| −576 | 576 | GetProgramName | +| −582 | 582 | SetPrompt | +| −588 | 588 | GetPrompt | +| −594 | 594 | SetProgramDir | +| −600 | 600 | GetProgramDir | +| −606 | 606 | SystemTagList | +| −612 | 612 | AssignLock | +| −618 | 618 | AssignLate | +| −624 | 624 | AssignPath | +| −630 | 630 | AssignAdd | +| −636 | 636 | RemAssignList | +| −642 | 642 | GetDeviceProc | +| −648 | 648 | FreeDeviceProc | +| −654 | 654 | LockDosList | +| −660 | 660 | UnLockDosList | +| −666 | 666 | AttemptLockDosList | +| −672 | 672 | RemDosEntry | +| −678 | 678 | AddDosEntry | +| −684 | 684 | FindDosEntry | +| −690 | 690 | NextDosEntry | +| −696 | 696 | MakeDosEntry | +| −702 | 702 | FreeDosEntry | +| −708 | 708 | IsFileSystem | +| −714 | 714 | Format | +| −720 | 720 | Relabel | +| −726 | 726 | Inhibit | +| −732 | 732 | AddBuffers | +| −738 | 738 | CompareDates | +| −744 | 744 | DateToStr | +| −750 | 750 | StrToDate | +| −756 | 756 | InternalLoadSeg | +| −762 | 762 | InternalUnLoadSeg | +| −768 | 768 | NewLoadSeg | +| −774 | 774 | AddSegment | +| −780 | 780 | FindSegment | +| −786 | 786 | RemSegment | +| −792 | 792 | CheckSignal | +| −798 | 798 | ReadArgs | +| −804 | 804 | FindArg | +| −810 | 810 | ReadItem | +| −816 | 816 | StrToLong | +| −822 | 822 | MatchFirst | +| −828 | 828 | MatchNext | +| −834 | 834 | MatchEnd | +| −840 | 840 | ParsePattern | +| −846 | 846 | MatchPattern | +| −852 | 852 | DosNameFromAnchor (private) | +| −858 | 858 | FreeArgs | +| −870 | 870 | FilePart | +| −876 | 876 | PathPart | +| −882 | 882 | AddPart | +| −888 | 888 | StartNotify | +| −894 | 894 | EndNotify | +| −900 | 900 | SetVar | +| −906 | 906 | GetVar | +| −912 | 912 | DeleteVar | +| −918 | 918 | FindVar | +| −924 | 924 | CliInit | +| −930 | 930 | CliInitNewcli | +| −936 | 936 | CliInitRun | +| −942 | 942 | WriteChars | +| −948 | 948 | PutStr | +| −954 | 954 | VPrintf | +| −966 | 966 | ParsePatternNoCase | +| −972 | 972 | MatchPatternNoCase | +| −978 | 978 | DosGetString (private) | +| −984 | 984 | SameDevice | +| −990 | 990 | SetOwner | --- diff --git a/14_references/exec_lvo_table.md b/14_references/exec_lvo_table.md index ff82c90..b54c5b1 100644 --- a/14_references/exec_lvo_table.md +++ b/14_references/exec_lvo_table.md @@ -21,10 +21,10 @@ | −102 | 102 | InitResident | | −108 | 108 | Alert | | −114 | 114 | Debug | -| −120 | 120 | Forbid | -| −126 | 126 | Permit | -| −132 | 132 | Disable | -| −138 | 138 | Enable | +| −120 | 120 | Disable | +| −126 | 126 | Enable | +| −132 | 132 | Forbid | +| −138 | 138 | Permit | | −144 | 144 | SetSR | | −150 | 150 | SuperState | | −156 | 156 | UserState |