Skip to content

Commit 108ceef

Browse files
authored
Fix potential integer overflow (microsoft#182)
When injecting a DLL into a process, it is possible that the process memory has been corrupted. The values in the import table for the process could be incorrect, which could cause an integer overflow when calculating the size of the new import table. Add code to protect against this to UPDATE_IMPORTS_XX.
1 parent ba2c4ec commit 108ceef

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

src/detours.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#pragma warning(disable:6102 6103) // /analyze warnings
4646
#endif
4747
#include <strsafe.h>
48+
#include <intsafe.h>
4849
#pragma warning(pop)
4950
#endif
5051

src/uimports.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,20 +140,44 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess,
140140
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress +
141141
inh.IMPORT_DIRECTORY.Size));
142142

143+
// Calculate new import directory size. Note that since inh is from another
144+
// process, inh could have been corrupted. We need to protect against
145+
// integer overflow in allocation calculations.
143146
DWORD nOldDlls = inh.IMPORT_DIRECTORY.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
144-
DWORD obRem = sizeof(IMAGE_IMPORT_DESCRIPTOR) * nDlls;
145-
DWORD obOld = obRem + sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls;
147+
DWORD obRem;
148+
if (DWordMult(sizeof(IMAGE_IMPORT_DESCRIPTOR), nDlls, &obRem) != S_OK) {
149+
DETOUR_TRACE(("too many new DLLs.\n"));
150+
goto finish;
151+
}
152+
DWORD obOld;
153+
if (DWordAdd(obRem, sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls, &obOld) != S_OK) {
154+
DETOUR_TRACE(("DLL entries overflow.\n"));
155+
goto finish;
156+
}
146157
DWORD obTab = PadToDwordPtr(obOld);
147-
DWORD obDll = obTab + sizeof(DWORD_XX) * 4 * nDlls;
158+
// Check for integer overflow.
159+
if (obTab < obOld) {
160+
DETOUR_TRACE(("DLL entries padding overflow.\n"));
161+
goto finish;
162+
}
163+
DWORD stSize;
164+
if (DWordMult(sizeof(DWORD_XX) * 4, nDlls, &stSize) != S_OK) {
165+
DETOUR_TRACE(("String table overflow.\n"));
166+
goto finish;
167+
}
168+
DWORD obDll;
169+
if (DWordAdd(obTab, stSize, &obDll) != S_OK) {
170+
DETOUR_TRACE(("Import table size overflow\n"));
171+
goto finish;
172+
}
148173
DWORD obStr = obDll;
149174
cbNew = obStr;
150175
for (n = 0; n < nDlls; n++) {
151-
cbNew += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
176+
if (DWordAdd(cbNew, PadToDword((DWORD)strlen(plpDlls[n]) + 1), &cbNew) != S_OK) {
177+
DETOUR_TRACE(("Overflow adding string table entry\n"));
178+
goto finish;
179+
}
152180
}
153-
154-
_Analysis_assume_(cbNew >
155-
sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nDlls + nOldDlls)
156-
+ sizeof(DWORD_XX) * 4 * nDlls);
157181
pbNew = new BYTE [cbNew];
158182
if (pbNew == NULL) {
159183
DETOUR_TRACE(("new BYTE [cbNew] failed.\n"));

0 commit comments

Comments
 (0)