This code gets the job done:
procedure DoJump(Address: Pointer);
asm
JMP Address
end;
const
X: Byte=$C3;//RET op code
procedure TriggerDEP;
begin
DoJump(@X);
end;
In the generated executable, the location where X
is stored is treated as data. As an alternative you could try executing code located on the stack:
procedure DoJump(Address: Pointer);
asm
JMP Address
end;
procedure TriggerDEP;
var
X: Byte;
begin
X := $C3;
DoJump(@X);
end;
Both of these raise access violation exceptions when DEP is active.
If you need to make sure that DEP is active, for example from a 32 bit process where it is optional, call this function:
procedure EnableDEP;
const
PROCESS_DEP_ENABLE: DWORD=$00000001;
var
SetProcessDEPPolicy: function(dwFlags: DWORD): BOOL; stdcall;
begin
SetProcessDEPPolicy := GetProcAddress(GetModuleHandle(kernel32), 'SetProcessDEPPolicy');
if Assigned(SetProcessDEPPolicy) then begin
SetProcessDEPPolicy(PROCESS_DEP_ENABLE);
end;
end;