1 | #include <windows.h>
|
---|
2 | #include <string.h>
|
---|
3 | #include "peexe.h"
|
---|
4 |
|
---|
5 | DWORD FAR PASCAL MyGetVersion();
|
---|
6 | UINT FAR _loadds PASCAL MyWinExec(LPCSTR lpszCmdLine, UINT fuShowCmd);
|
---|
7 |
|
---|
8 | BOOL GetPEFileHeader (LPVOID lpFile, PIMAGE_FILE_HEADER pHeader);
|
---|
9 | BOOL GetPEOptionalHeader (LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader);
|
---|
10 |
|
---|
11 | #ifdef __WATCOMC__
|
---|
12 | typedef DWORD (FAR * WINAPI * FUNC_GetVersion)(void);
|
---|
13 | typedef UINT (FAR * WINAPI * FUNC_WinExec)(LPCSTR, UINT);
|
---|
14 | #else
|
---|
15 | typedef DWORD (FAR * WINAPI FUNC_GetVersion)(void);
|
---|
16 | typedef UINT (FAR * WINAPI FUNC_WinExec)(LPCSTR, UINT);
|
---|
17 | #endif
|
---|
18 |
|
---|
19 | BYTE oldcodeVER;
|
---|
20 | DWORD olddataVER;
|
---|
21 | UINT selVER;
|
---|
22 | BYTE oldcodeEXEC;
|
---|
23 | DWORD olddataEXEC;
|
---|
24 | UINT selEXEC;
|
---|
25 | BYTE FAR *jumpVER;
|
---|
26 | BYTE FAR *jumpEXEC;
|
---|
27 |
|
---|
28 | BOOL fUnloaded = FALSE;
|
---|
29 | BOOL fInit = FALSE;
|
---|
30 |
|
---|
31 | char szPEPath[256] = {0};
|
---|
32 |
|
---|
33 | //*****************************************************************************************
|
---|
34 | //*****************************************************************************************
|
---|
35 | int FAR _loadds CALLBACK LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeap, LPSTR lpszCmdLine)
|
---|
36 | {
|
---|
37 | FUNC_GetVersion getver;
|
---|
38 | FUNC_WinExec winexec;
|
---|
39 | DWORD FAR *addr;
|
---|
40 |
|
---|
41 | if (fInit == FALSE) {
|
---|
42 | fInit = TRUE;
|
---|
43 |
|
---|
44 | GetProfileString("Odin", "PEPath", "PE.EXE", szPEPath, sizeof(szPEPath));
|
---|
45 | getver = (FUNC_GetVersion)&GetVersion;
|
---|
46 | selVER = AllocSelector(0);
|
---|
47 | PrestoChangoSelector(SELECTOROF(getver), selVER);
|
---|
48 |
|
---|
49 | jumpVER = MAKELP(selVER, OFFSETOF(getver));
|
---|
50 | addr = (DWORD FAR *)(jumpVER+1);
|
---|
51 | oldcodeVER = *jumpVER;
|
---|
52 | olddataVER = *addr;
|
---|
53 | *jumpVER = 0xEA; //jmp
|
---|
54 | *addr = (DWORD)&MyGetVersion;
|
---|
55 |
|
---|
56 | winexec = (FUNC_WinExec)&WinExec;
|
---|
57 | selEXEC = AllocSelector(0);
|
---|
58 | PrestoChangoSelector(SELECTOROF(winexec), selEXEC);
|
---|
59 |
|
---|
60 | jumpEXEC = MAKELP(selEXEC, OFFSETOF(winexec));
|
---|
61 | addr = (DWORD FAR *)(jumpEXEC+1);
|
---|
62 | oldcodeEXEC = *jumpEXEC;
|
---|
63 | olddataEXEC = *addr;
|
---|
64 | *jumpEXEC = 0xEA; //jmp
|
---|
65 | *addr = (DWORD)&MyWinExec;
|
---|
66 | }
|
---|
67 | return 1;
|
---|
68 | }
|
---|
69 | //*****************************************************************************************
|
---|
70 | //*****************************************************************************************
|
---|
71 | int FAR _loadds PASCAL WEP(int entry)
|
---|
72 | {
|
---|
73 | DWORD FAR *addr;
|
---|
74 |
|
---|
75 | /* Your WEP functionality goes here */
|
---|
76 | if(!fUnloaded) {
|
---|
77 | fUnloaded = TRUE;
|
---|
78 |
|
---|
79 | //restore entrypoints
|
---|
80 | addr = (DWORD FAR *)(jumpVER + 1);
|
---|
81 | *jumpVER = oldcodeVER;
|
---|
82 | *addr = olddataVER;
|
---|
83 |
|
---|
84 | addr = (DWORD FAR *)(jumpEXEC + 1);
|
---|
85 | *jumpEXEC = oldcodeEXEC;
|
---|
86 | *addr = olddataEXEC;
|
---|
87 | }
|
---|
88 | return 1;
|
---|
89 | }
|
---|
90 | //*****************************************************************************************
|
---|
91 | //*****************************************************************************************
|
---|
92 | DWORD FAR PASCAL MyGetVersion()
|
---|
93 | {
|
---|
94 | return 0x00005F0C;
|
---|
95 | }
|
---|
96 | //*****************************************************************************************
|
---|
97 | //*****************************************************************************************
|
---|
98 | UINT FAR _loadds PASCAL MyWinExec(LPCSTR lpszCmdLine, UINT fuShowCmd)
|
---|
99 | {
|
---|
100 | LPSTR cmdline, tmp;
|
---|
101 | UINT ret;
|
---|
102 | OFSTRUCT of = {0};
|
---|
103 | HFILE hFile = 0;
|
---|
104 | int hdrsize;
|
---|
105 | IMAGE_DOS_HEADER doshdr;
|
---|
106 | IMAGE_FILE_HEADER fh;
|
---|
107 | IMAGE_OPTIONAL_HEADER oh;
|
---|
108 | DWORD FAR *addr;
|
---|
109 | UINT bytesRead;
|
---|
110 | char FAR *header;
|
---|
111 | HGLOBAL hMem1 = 0, hMem2 = 0, hMem3 = 0, hMem4 = 0;
|
---|
112 | BOOL fFail = TRUE;
|
---|
113 |
|
---|
114 | of.cBytes = sizeof(OFSTRUCT);
|
---|
115 |
|
---|
116 | hMem1 = GlobalAlloc(GPTR, strlen(lpszCmdLine)+1);
|
---|
117 | cmdline = GlobalLock(hMem1);
|
---|
118 | if(cmdline == NULL) goto calloldfunc;
|
---|
119 |
|
---|
120 | strcpy(cmdline, lpszCmdLine);
|
---|
121 |
|
---|
122 | while(*cmdline == ' ') cmdline++;
|
---|
123 | tmp = cmdline;
|
---|
124 | while(*tmp != ' ' && *tmp != 0) tmp++;
|
---|
125 | tmp++;
|
---|
126 | *tmp = 0;
|
---|
127 |
|
---|
128 | hFile = OpenFile(cmdline, &of, OF_READ);
|
---|
129 | bytesRead = _lread(hFile, &doshdr, sizeof(doshdr));
|
---|
130 | if(bytesRead != sizeof(doshdr)) goto calloldfunc;
|
---|
131 | if(doshdr.e_magic != IMAGE_DOS_SIGNATURE) goto calloldfunc;
|
---|
132 | hdrsize = doshdr.e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER);
|
---|
133 |
|
---|
134 | _llseek(hFile, 0, 0);
|
---|
135 | hMem3 = GlobalAlloc(GPTR, hdrsize);
|
---|
136 | header = GlobalLock(hMem3);
|
---|
137 | if(header == NULL) goto calloldfunc;
|
---|
138 |
|
---|
139 | bytesRead = _lread(hFile, header, hdrsize);
|
---|
140 | if(bytesRead != hdrsize) {
|
---|
141 | goto calloldfunc;
|
---|
142 | }
|
---|
143 | if(GetPEFileHeader (header, &fh) == FALSE) {
|
---|
144 | goto calloldfunc;
|
---|
145 | }
|
---|
146 | if(GetPEOptionalHeader (header, &oh) == FALSE) {
|
---|
147 | goto calloldfunc;
|
---|
148 | }
|
---|
149 |
|
---|
150 | if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
|
---|
151 | goto calloldfunc;
|
---|
152 | }
|
---|
153 | if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
|
---|
154 | goto calloldfunc;
|
---|
155 | }
|
---|
156 | //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
|
---|
157 | if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
|
---|
158 | goto calloldfunc;
|
---|
159 | }
|
---|
160 |
|
---|
161 | tmp = cmdline;
|
---|
162 | hMem4 = hMem1;
|
---|
163 |
|
---|
164 | hMem1 = GlobalAlloc(GPTR, strlen(tmp)+16+strlen(szPEPath));
|
---|
165 | cmdline = GlobalLock(hMem1);
|
---|
166 | if(cmdline == NULL) {
|
---|
167 | goto calloldfunc;
|
---|
168 | }
|
---|
169 |
|
---|
170 | strcpy(cmdline, szPEPath);
|
---|
171 | strcat(cmdline, " ");
|
---|
172 | strcat(cmdline, tmp);
|
---|
173 |
|
---|
174 | fFail = FALSE;
|
---|
175 |
|
---|
176 | calloldfunc:
|
---|
177 | if(hMem4) {
|
---|
178 | GlobalUnlock(hMem4);
|
---|
179 | GlobalFree(hMem4);
|
---|
180 | }
|
---|
181 | if(hMem3) {
|
---|
182 | GlobalUnlock(hMem3);
|
---|
183 | GlobalFree(hMem3);
|
---|
184 | }
|
---|
185 | if(hMem2) {
|
---|
186 | GlobalUnlock(hMem2);
|
---|
187 | GlobalFree(hMem2);
|
---|
188 | }
|
---|
189 | if(hFile)
|
---|
190 | _lclose(hFile);
|
---|
191 |
|
---|
192 | addr = (DWORD FAR *)(jumpEXEC + 1);
|
---|
193 | *jumpEXEC = oldcodeEXEC;
|
---|
194 | *addr = olddataEXEC;
|
---|
195 |
|
---|
196 | if(fFail) {
|
---|
197 | ret = WinExec(lpszCmdLine, fuShowCmd);
|
---|
198 | }
|
---|
199 | else {
|
---|
200 | ret = WinExec(cmdline, fuShowCmd);
|
---|
201 | if(ret >= 32) {
|
---|
202 | DWORD tickcount1, tickcount2;
|
---|
203 |
|
---|
204 | //give PE a chance to load the exe file
|
---|
205 | tickcount1 = GetTickCount();
|
---|
206 | do {
|
---|
207 | Yield();
|
---|
208 | tickcount2 = GetTickCount();
|
---|
209 | }
|
---|
210 | while(tickcount2 - tickcount1 < 2000UL);
|
---|
211 | }
|
---|
212 | }
|
---|
213 |
|
---|
214 | *jumpEXEC = 0xEA; //jmp
|
---|
215 | *addr = (DWORD)&MyWinExec;
|
---|
216 |
|
---|
217 | if(hMem1) {
|
---|
218 | GlobalUnlock(hMem1);
|
---|
219 | GlobalFree(hMem1);
|
---|
220 | }
|
---|
221 | return ret;
|
---|
222 | }
|
---|
223 | //******************************************************************************
|
---|
224 | //******************************************************************************
|
---|
225 | BOOL GetPEFileHeader (LPVOID lpFile, PIMAGE_FILE_HEADER pHeader)
|
---|
226 | {
|
---|
227 | if(*(WORD *)lpFile == IMAGE_DOS_SIGNATURE &&
|
---|
228 | *(DWORD *)PE_HEADER (lpFile) == IMAGE_NT_SIGNATURE)
|
---|
229 | {
|
---|
230 | memcpy ((LPVOID)pHeader, PEHEADEROFF (lpFile), sizeof (IMAGE_FILE_HEADER));
|
---|
231 | return TRUE;
|
---|
232 | }
|
---|
233 | else return FALSE;
|
---|
234 | }
|
---|
235 | //******************************************************************************
|
---|
236 | //******************************************************************************
|
---|
237 | BOOL GetPEOptionalHeader (LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader)
|
---|
238 | {
|
---|
239 | if(*(WORD *)lpFile == IMAGE_DOS_SIGNATURE &&
|
---|
240 | *(DWORD *)PE_HEADER (lpFile) == IMAGE_NT_SIGNATURE)
|
---|
241 | {
|
---|
242 | memcpy ((LPVOID)pHeader, OPTHEADEROFF (lpFile), sizeof (IMAGE_OPTIONAL_HEADER));
|
---|
243 | return TRUE;
|
---|
244 | }
|
---|
245 | else return FALSE;
|
---|
246 | }
|
---|
247 | //*****************************************************************************************
|
---|
248 | //*****************************************************************************************
|
---|