Puzzle x: enum array.
Consider the case where you want to
dllcall a function declared as
void f(DPI_AWARENESS values[4]), where
DPI_AWARENESS is an enumeration defined as,
Code: Select all
// c++
enum DPI_AWARENESS {
DPI_AWARENESS_INVALID = -1,
DPI_AWARENESS_UNAWARE = 0,
DPI_AWARENESS_SYSTEM_AWARE = 1,
DPI_AWARENESS_PER_MONITOR_AWARE = 2
};
The function simply fills the array you pass with some predefined values (some combination of some or all of -1,0,1 or 2). Your problem is that the function resides in a dll which exists in many different versions, the implementation of the function is the same, but the dll is compiled with different compilers and/or optimisations, so the underlying type of the enum values vary.
Puzzle objective: Safely (dll)call the function
void f(DPI_AWARENESS values[4]) and correctly interpret and print the result, regardless of which version of the function is called. Your code should work even if the function changed the values it put in the array, however, the enum definition is assumed to never change. Your code should work for any of the underlying types,
char,
short and
int.
Puzzle rules: You are not allowed to analyse or store the return value of
P(). You cannot modify the function
P() or its return value.
Code:
In the code below, the function
P() randomly returns a pointer to one of two versions of the the function
f, your code should produce the same output regardless of which version is returned.
Code: Select all
; Any code here...
dllcall(P(), ..., "cdecl") ; complete this call
; Any code here...
; Do not modify this function:
; You should not, and need not, look at this code,
P(){
local
static flProtect:=0x40, flAllocationType:=0x1000 ; PAGE_EXECUTE_READWRITE ; MEM_COMMIT
static raw32A:=[2347075925,13043781,4294967295,278727,3338665984,2112,1086783488,12,2428722432]
static raw64A:=[4294902215,1103626239,4,138528512,0,803271,3271557120,2425393296]
static raw32B:=[2347075925,12978245,21022463,37799424,54576640,2428722432]
static raw64B:=[3338600902,3321889089,3321889345,3271557953]
random r, 0,1
x := r ? "A" : "B"
bin:=DllCall("Kernel32.dll\VirtualAlloc", "Uptr",0, "Ptr", (raw:=A_PtrSize==4?raw32%x%:raw64%x%).length()*4, "Uint", flAllocationType, "Uint", flProtect, "Ptr")
for k, i in raw
NumPut(i,bin+(k-1)*4,"Int")
return bin
}