Revision | d2d1b6db855af428e16af5e4c53806f06932bc23 (tree) |
---|---|
Time | 2011-01-23 07:34:28 |
Author | Face |
Commiter | Face |
OrbiterExtensions: added hooking of RecordEvent
@@ -10,22 +10,43 @@ | ||
10 | 10 | |
11 | 11 | #define DOCKSTRUCTOFFSET_CURRENTDOCKOBJECT 0x48 |
12 | 12 | #define ADDRESS_GETDOCKSTATUS 0x00476210 |
13 | +#define VESSELSTRUCTOFFSET_RECORDING 0x0D32 | |
14 | +#define ADDRESS_RECORDEVENT 0x00476FA0 | |
15 | +#define ADDRESS_INTERNALRECORDEVENT 0x00465FB0 | |
13 | 16 | |
14 | 17 | // ============================================================== |
15 | 18 | // Global variables |
16 | 19 | |
17 | 20 | #include "orbitersdk.h" |
18 | 21 | #include <map> |
22 | +#include <queue> | |
19 | 23 | |
20 | 24 | namespace OrbiterExtensions |
21 | 25 | |
22 | 26 | { |
23 | 27 | |
28 | +struct EventEntry | |
29 | +{ | |
30 | + double MJD; | |
31 | + char *event_type; | |
32 | + char *event; | |
33 | +}; | |
34 | + | |
35 | +struct EventQueue | |
36 | +{ | |
37 | + CRITICAL_SECTION access; | |
38 | + int backlog; | |
39 | + std::queue<EventEntry> queue; | |
40 | +}; | |
41 | + | |
24 | 42 | std::map<VESSEL *, OBJHANDLE> g_DockLink; |
43 | +std::map<VESSEL *, EventQueue> g_Events; | |
25 | 44 | std::map<VESSEL *, int> g_Handles; |
26 | 45 | |
27 | 46 | DWORD g_Hook; |
28 | -byte g_original[10]={0x8b,0x44,0x24,0x04,0x8b,0x40,0x48,0xc2,0x04,0x00}; | |
47 | +byte g_GetDockStatusOriginal[9]={0x8b,0x44,0x24,0x04,0x8b,0x40,0x48,0xc2,0x04}; | |
48 | +byte g_RecordEventOriginal[9]={0x8B,0x09,0x80,0xB9,0x32,0x0D,0x00,0x00,0x00}; | |
49 | + | |
29 | 50 | //The following array is: |
30 | 51 | //_asm |
31 | 52 | //{ |
@@ -35,7 +56,7 @@ | ||
35 | 56 | // jmp dword ptr [GetDockStatus]; //Dynamically detected address |
36 | 57 | // nop; |
37 | 58 | //} |
38 | -byte g_code[10] = {0x58, 0x51, 0x50, 0xff, 0x25, 0, 0, 0, 0, 0x90}; | |
59 | +byte g_Code[9] = {0x58, 0x51, 0x50, 0xff, 0x25, 0, 0, 0, 0}; | |
39 | 60 | |
40 | 61 | OBJHANDLE _stdcall GetDockStatus(VESSEL *vessel, DOCKHANDLE dock) |
41 | 62 | { |
@@ -46,6 +67,38 @@ | ||
46 | 67 | return *(OBJHANDLE *)(void *)((char *)dock+DOCKSTRUCTOFFSET_CURRENTDOCKOBJECT); |
47 | 68 | } |
48 | 69 | |
70 | +void _stdcall RecordEvent(VESSEL *vessel, const char *event_type, const char *event) | |
71 | +{ | |
72 | + //Do my own RecordEvent | |
73 | + std::map<VESSEL *, EventQueue>::iterator el=g_Events.find(vessel); | |
74 | + if (el!=g_Events.end()) | |
75 | + { | |
76 | + EnterCriticalSection(&el->second.access); | |
77 | + if (el->second.queue.size()<el->second.backlog) | |
78 | + { | |
79 | + EventEntry entry; | |
80 | + entry.MJD=oapiGetSimMJD(); | |
81 | + entry.event=new char[strlen(event)+1]; | |
82 | + strcpy(entry.event, event); | |
83 | + entry.event_type=new char[strlen(event_type)+1]; | |
84 | + strcpy(entry.event_type, event_type); | |
85 | + el->second.queue.push(entry); | |
86 | + } | |
87 | + LeaveCriticalSection(&el->second.access); | |
88 | + } | |
89 | + //Original function content | |
90 | + if (*(*(char **)vessel+VESSELSTRUCTOFFSET_RECORDING)==0) return; | |
91 | + _asm | |
92 | + { | |
93 | + push event | |
94 | + push event_type | |
95 | + mov eax, vessel | |
96 | + mov ecx,dword ptr ds:[eax] | |
97 | + mov eax,ADDRESS_INTERNALRECORDEVENT | |
98 | + call eax | |
99 | + } | |
100 | +} | |
101 | + | |
49 | 102 | int WriteCode(void *address, void *code, DWORD len) |
50 | 103 | { |
51 | 104 | //Get process information |
@@ -87,25 +140,35 @@ | ||
87 | 140 | // 1 if already hooked |
88 | 141 | // -1 if already initialized by handle |
89 | 142 | // -2 if already hooked by some other system |
90 | -__declspec(dllexport) int __cdecl Init(VESSEL *handle) | |
143 | +__declspec(dllexport) int __cdecl Init(VESSEL *handle, int flags=0) | |
91 | 144 | { |
92 | 145 | if (g_Handles.find(handle)!=g_Handles.end()) return -1; |
93 | 146 | g_Handles[handle]=1; |
147 | + | |
148 | + if (memcmp((void *)g_GetDockStatusOriginal, (void *)ADDRESS_GETDOCKSTATUS, 9)!=0 || | |
149 | + memcmp((void *)g_RecordEventOriginal, (void *)ADDRESS_RECORDEVENT, 9)!=0) | |
150 | + { | |
151 | + if (g_Handles.size()==1) return -2; | |
152 | + return 1; | |
153 | + } | |
154 | + | |
94 | 155 | union |
95 | 156 | { |
96 | 157 | void *pointer; |
97 | 158 | byte bytes[4]; |
98 | 159 | DWORD value; |
99 | 160 | } p; |
161 | + | |
100 | 162 | g_Hook=(DWORD)(void *)GetDockStatus; |
101 | 163 | p.pointer=(void *)&g_Hook; |
102 | - for(int i=0;i<4;i++) g_code[5+i] = p.bytes[i]; | |
103 | - if (memcmp((void *)g_original, (void *)ADDRESS_GETDOCKSTATUS, 10)!=0) | |
104 | - { | |
105 | - if (g_Handles.size()==1) return -2; | |
106 | - return 1; | |
107 | - } | |
108 | - WriteCode((void *)ADDRESS_GETDOCKSTATUS, (void *)g_code, 10); | |
164 | + for(int i=0;i<4;i++) g_Code[5+i] = p.bytes[i]; | |
165 | + WriteCode((void *)ADDRESS_GETDOCKSTATUS, (void *)g_Code, 9); | |
166 | + | |
167 | + g_Hook=(DWORD)(void *)RecordEvent; | |
168 | + p.pointer=(void *)&g_Hook; | |
169 | + for(int i=0;i<4;i++) g_Code[5+i] = p.bytes[i]; | |
170 | + WriteCode((void *)ADDRESS_RECORDEVENT, (void *)g_Code, 9); | |
171 | + | |
109 | 172 | return 0; |
110 | 173 | } |
111 | 174 |
@@ -119,8 +182,9 @@ | ||
119 | 182 | if (g_Handles.find(handle)==g_Handles.end()) return -1; |
120 | 183 | g_Handles.erase(handle); |
121 | 184 | if (g_Handles.size()>0) return 1; |
122 | - if (memcmp((void *)g_code, (void *)ADDRESS_GETDOCKSTATUS, 10)!=0) return -2; | |
123 | - WriteCode((void *)ADDRESS_GETDOCKSTATUS, (void *)g_original, 10); | |
185 | + if (memcmp((void *)g_Code, (void *)ADDRESS_RECORDEVENT, 10)!=0) return -2; | |
186 | + WriteCode((void *)ADDRESS_GETDOCKSTATUS, (void *)g_GetDockStatusOriginal, 10); | |
187 | + WriteCode((void *)ADDRESS_RECORDEVENT, (void *)g_RecordEventOriginal, 10); | |
124 | 188 | return 0; |
125 | 189 | } |
126 | 190 |
@@ -140,7 +204,7 @@ | ||
140 | 204 | return 0; |
141 | 205 | } |
142 | 206 | |
143 | -__declspec(dllexport) float __cdecl GetVersion(){return (float)0.1;} | |
207 | +__declspec(dllexport) float __cdecl GetVersion(){return (float)0.2;} | |
144 | 208 | } |
145 | 209 | |
146 | 210 | } |
\ No newline at end of file |