2013-05-01 3 views
5

바이트 배열을 생성 한 다음 Windows에서 정상적인 코드처럼 실행할 수 있습니까? 어셈블리 코드가 있다고 가정 해보십시오.Delphi에서 즉시 코드를 컴파일하고 실행할 수 있습니까?

inc ecx 

은 프로그램의 일부입니다.

00000035 41 

바이트의 배열을 만들 수 위의 바이트를 기입하고 그래서를 execute- 할 수 있을까 : 우리가 NASM 컴파일 후 우리는 위의 라인이 이런 식으로 변환하는 EXE 파일을 얻을 증분이 실제로 발생합니까?

나는 매우 간단한 해석 언어를 만들었지 만 해석되기 때문에 매우 느리다. 나는 진짜 컴파일러를 쓰고 싶지는 않지만 빨리 컴파일하고 실행하고 싶습니다.

답변

14

물론입니다. 데이터 실행 방지 기능을 지원하는 프로세서 및 운영 체제는 중단 될 수 있지만 쉽게 우회 할 수 있습니다. VirtualProtect을 호출하여 메모리 블록을 실행 가능으로 표시하십시오. 실행을 계획중인 메모리를 할당하려면 VirtualAlloc을 사용하는 것이 가장 좋습니다. 그렇게하면 실행 가능한 코드에만 전적으로 사용되는 전체 메모리 페이지가 생깁니다. VirtualProtect을 호출하여 GetMem 실행 파일로 할당 한 임의의 메모리를 실제로 만들면 전체 페이지를 그런 식으로 표시하므로 우연히 데이터을 실행 파일로 표시 할 수 있습니다. 해당 데이터가 유출되면 실행될 수 있습니다. 이는 DEP가 보호해야 할 대상이므로 데이터와 실행 코드를 별도로 보호 된 영역에 보관하는 것이 좋습니다.

텍스트 코드를 기계 코드 으로 변환하는 작업은입니다. 따라서 실제 컴파일러를 쓰고 싶지 않으면 결국 머신 코드를 생성하고 싶지 않을 수도 있습니다.

+0

이라면 스택 포인터로로드 된 하나의 레지스터 만 있으면됩니다. 그것은 "컴파일"이지만 모든 EXE 헤더없이 외부 라이브러리 등을 연결합니다. 그래서 쉬워야합니다. – Tom

+1

여전히 위치를 변경 (픽스 업)해야합니다. 어떤 데이터도 사용하지 않거나 (시작시 레지스터에 전달되는 포인터를 통해 간접적으로 주소 지정하는 경우) 분기 및 PIC 근처에서만 사용해야합니다. –

1

저는 데이터 실행 방지 (DEP) 기능이있는 최신 프로세서가 이것을 허용하지 않을 것이라고 생각합니다. 그런 목적으로 사용할 수있는 여러 개의 파스칼 스크립팅 라이브러리가 있습니다.

+0

저는 RemObjects Pascal Script와 같은 것으로 알고 있습니다. 하지만 저는 파스칼 어로 쓰고 싶지 않습니다. 정말 간단한 것이 필요합니다. – Tom

+3

DEP는 VirtualAlloc() 또는 VirtualProtect()를 통해 명시 적으로 실행하도록 표시된 메모리에서 명령 실행을 막지 않습니다. VCL 및 ATL과 같은 프레임 워크가 있으며, 콜백 썽크로 사용하기 위해 실행 가능한 메모리 척을 동적으로 할당합니다. DEP는이를 잘 처리합니다. –

+1

표현식 평가 기가 있습니다. 하지만 그들은 대개 스택 머신을 모방하므로 코드가 PIC –

7
const 
    size = 32768; 
type 
    TFuncInt = function(param: Integer): Integer; // EAX -> EAX 
    TByteArray = array[0..size-1] of Byte; 
    PByteArray = ^TByteArray; 
var 
    arr: PByteArray; 
    func_param: Integer; 
    func_result: Integer; 
begin 
    arr := VirtualAlloc(nil, size, $3000, $40); 
    if arr <> nil then begin 
    arr[0] := $40; // inc EAX 
    arr[1] := $C3; // ret 
    func_param := 77; 
    func_result := TFuncInt(arr)(func_param); // 78 
    VirtualFree(arr, 0, $8000); 
    end; 
end; 
+0

멋지다. 고마워! – Tom

+1

@RobKennedy - 귀하의 코드 버전이 컴파일되지 않습니다. 'Page_Execute_ReadWrite'는 델파이 7에서는 정의되어 있지 않습니다. 수동으로 정의해야합니다. 또는 대신 숫자 값을 사용하십시오. –

+0

그럼 정의하십시오. 당신의 개발 환경이 얼마나 시대에 뒤떨어져 있는지 나는 상관하지 않는다. 맨손으로 숫자를 사용하지 마십시오. 코드를 읽는 사람에게는 아무런 의미가 없습니다. –

관련 문제