| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -48,6 +48,26 @@ struct MSVC_MPTR {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    intptr_t this_shift;
 | 
					 | 
					 | 
					 | 
					    intptr_t this_shift;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					};
 | 
					 | 
					 | 
					 | 
					};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static uint32_t *follow_jmp(void *ptr)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    uint8_t *p = (uint8_t*)ptr;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (;;)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        switch (*p)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        case 0xE9:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            p += 5 + *(int32_t*)(p+1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        case 0xEB:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            p += 2 + *(int8_t*)(p+1);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        default:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return (uint32_t*)p;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					bool DFHack::is_vmethod_pointer_(void *pptr)
 | 
					 | 
					 | 
					 | 
					bool DFHack::is_vmethod_pointer_(void *pptr)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{
 | 
					 | 
					 | 
					 | 
					{
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    auto pobj = (MSVC_MPTR*)pptr;
 | 
					 | 
					 | 
					 | 
					    auto pobj = (MSVC_MPTR*)pptr;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -55,7 +75,7 @@ bool DFHack::is_vmethod_pointer_(void *pptr)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // MSVC implements pointers to vmethods via thunks.
 | 
					 | 
					 | 
					 | 
					    // MSVC implements pointers to vmethods via thunks.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // This expects that they all follow a very specific pattern.
 | 
					 | 
					 | 
					 | 
					    // This expects that they all follow a very specific pattern.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    auto pval = (unsigned*)pobj->method;
 | 
					 | 
					 | 
					 | 
					    auto pval = follow_jmp(pobj->method);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    switch (pval[0]) {
 | 
					 | 
					 | 
					 | 
					    switch (pval[0]) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    case 0x20FF018BU: // mov eax, [ecx]; jmp [eax]
 | 
					 | 
					 | 
					 | 
					    case 0x20FF018BU: // mov eax, [ecx]; jmp [eax]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    case 0x60FF018BU: // mov eax, [ecx]; jmp [eax+0x??]
 | 
					 | 
					 | 
					 | 
					    case 0x60FF018BU: // mov eax, [ecx]; jmp [eax+0x??]
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -71,7 +91,7 @@ int DFHack::vmethod_pointer_to_idx_(void *pptr)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    auto pobj = (MSVC_MPTR*)pptr;
 | 
					 | 
					 | 
					 | 
					    auto pobj = (MSVC_MPTR*)pptr;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (!pobj->method || pobj->this_shift != 0) return -1;
 | 
					 | 
					 | 
					 | 
					    if (!pobj->method || pobj->this_shift != 0) return -1;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    auto pval = (unsigned*)pobj->method;
 | 
					 | 
					 | 
					 | 
					    auto pval = follow_jmp(pobj->method);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    switch (pval[0]) {
 | 
					 | 
					 | 
					 | 
					    switch (pval[0]) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    case 0x20FF018BU: // mov eax, [ecx]; jmp [eax]
 | 
					 | 
					 | 
					 | 
					    case 0x20FF018BU: // mov eax, [ecx]; jmp [eax]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return 0;
 | 
					 | 
					 | 
					 | 
					        return 0;
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |