Browse Source

Merge branch 'new-get-graphics-offsets'

Added offsets to support Windows 10 Creator's Update
Richard Stanway 8 years ago
parent
commit
2ae706782c
1 changed files with 118 additions and 37 deletions
  1. 118 37
      plugins/win-capture/get-graphics-offsets/d3d9-offsets.cpp

+ 118 - 37
plugins/win-capture/get-graphics-offsets/d3d9-offsets.cpp

@@ -81,46 +81,131 @@ static inline void d3d9_free(d3d9_info &info)
 
 #ifdef _WIN64
 
-#define CMP_SIZE 21
-
-static const uint8_t mask[CMP_SIZE] =
-{0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x00,
- 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00};
-
-static const uint8_t mask_cmp[CMP_SIZE] =
-{0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x75, 0x00,
- 0x40, 0xB8, 0x00, 0x00, 0x00, 0x00};
+#define MAX_CMP_SIZE 22
+
+static const uint8_t mask[][MAX_CMP_SIZE] = {
+	{
+		0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0x00,
+		0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00
+	},
+	{
+		0xF8, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0x00,
+		0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00
+	}
+};
+
+static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
+	/*
+	* Windows 7
+	* 48 8B 83 B8 3D 00 00                    mov     rax, [rbx+3DB8h]
+	* 44 39 B8 68 50 00 00                    cmp     [rax+5068h], r15d
+	* 75 12                                   jnz     short loc_7FF7AA90530
+	* 41 B8 F9 19 00 00                       mov     r8d, 19F9h
+	*/
+	{
+		0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x44, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x75, 0x00,
+		0x40, 0xB8, 0x00, 0x00, 0x00, 0x00
+	},
+	/*
+	* Windows ???+
+	* 49 8B 87 78 41 00 00                    mov     rax, [r15+4178h]
+	* 39 98 E0 51 00 00                       cmp     [rax+51E0h], ebx
+	* 75 12                                   jnz     short loc_1800AEC9C
+	* 41 B9 C3 1A 00 00                       mov     r9d, 1AC3h
+	*/
+	{
+		0x48, 0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x75, 0x00,
+		0x40, 0xB8, 0x00, 0x00, 0x00, 0x00
+	}
+};
+
+// Offset into the code for the numbers we're interested in
+static const uint32_t code_offsets[][2] = {
+	{3, 10},
+	{3, 9},
+};
 #else
 
-#define CMP_SIZE 19
+#define MAX_CMP_SIZE 20
+
+static const uint8_t mask[][MAX_CMP_SIZE] = {
+	{
+		0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0x00,
+		0xFF, 0x00, 0x00, 0x00, 0x00
+	},
+	{
+		0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
+		0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+		0xFF, 0x00,
+		0xFF, 0x00, 0x00, 0x00, 0x00
+	}
+};
 
-static const uint8_t mask[CMP_SIZE] =
-{0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x00,
- 0xFF, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t mask_cmp[][MAX_CMP_SIZE] = {
+	/*
+	* Windows 7+
+	* 8B 83 E8 29 00 00      mov     eax, [ebx+29E8h]
+	* 39 B0 80 4B 00 00      cmp     [eax+4B80h], esi
+	* 75 14                  jnz     short loc_754CD9E1
+	* 68 F9 19 00 00         push    19F9h
+	*/
+	{
+		0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x75, 0x00,
+		0x68, 0x00, 0x00, 0x00, 0x00
+	},
+
+	/* Windows 10 Creator's Update+
+	* 8B 86 F8 2B 00 00      mov     eax, [esi+2BF8h]
+	* 83 B8 00 4D 00 00 00   cmp     dword ptr [eax+4D00h], 0
+	* 75 0F                  jnz     short loc_100D793C
+	* 68 C3 1A 00 00         push    1AC3h
+	*/
+	{
+		0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
+		0x83, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x75, 0x00,
+		0x68, 0x00, 0x00, 0x00, 0x00
+	}
+};
 
-static const uint8_t mask_cmp[CMP_SIZE] =
-{0x8B, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x39, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x75, 0x00,
- 0x68, 0x00, 0x00, 0x00, 0x00};
+// Offset into the code for the numbers we're interested in
+static const uint32_t code_offsets[][2] = {
+	{2, 8},
+	{2, 8},
+};
 #endif
 
 #define MAX_FUNC_SCAN_BYTES 200
 
-static inline bool pattern_matches(uint8_t *byte)
+static inline bool pattern_matches(uint8_t *byte, uint32_t *offset1,
+	uint32_t *offset2)
 {
-	for (size_t i = 0; i < CMP_SIZE; i++) {
-		if ((byte[i] & mask[i]) != mask_cmp[i])
-			return false;
+	for (size_t j = 0; j < sizeof(mask) / sizeof(mask[0]); j++) {
+		for (size_t i = 0; i < MAX_CMP_SIZE; i++) {
+			if ((byte[i] & mask[j][i]) != mask_cmp[j][i])
+				goto next_signature;
+		}
+
+		*offset1 = code_offsets[j][0];
+		*offset2 = code_offsets[j][1];
+
+		return true;
+next_signature:;
 	}
 
-	return true;
+	return false;
 }
 
 void get_d3d9_offsets(struct d3d9_offsets *offsets)
@@ -138,16 +223,12 @@ void get_d3d9_offsets(struct d3d9_offsets *offsets)
 		offsets->present_swap = vtable_offset(info.module, info.swap,
 				3);
 
+		uint32_t offset1, offset2;
 		for (size_t i = 0; i < MAX_FUNC_SCAN_BYTES; i++) {
-			if (pattern_matches(&crr[i])) {
+			if (pattern_matches(&crr[i], &offset1, &offset2)) {
 #define get_offset(x) *(uint32_t*)&crr[i + x]
-#ifdef _WIN64
-				uint32_t off1 = get_offset(3);
-				uint32_t off2 = get_offset(9);
-#else
-				uint32_t off1 = get_offset(2);
-				uint32_t off2 = get_offset(8);
-#endif
+				uint32_t off1 = get_offset(offset1);
+				uint32_t off2 = get_offset(offset2);
 
 				/* check to make sure offsets are within
 				 * expected values */