2016-12-13 11 views
0

스택에 메모리를 할당하기 위해 ntdll.dll 만 사용하는 API 호출이나 다른 유사한 방법이 있습니까?C - ntdll만을 사용하는 스택 할당

나는 alloca()을 알고 있지만, 단지 ntdll.dll의 기능 만 사용할 수 있기 때문에 사용할 수 없습니다.

감사합니다.

+0

그런 기능은 없습니다. 직접 쉽게 쓸 수 있습니다. –

+0

OS가 스택 할당을 제공하지 않는다면 모든 단일 사용자 기능이 프롤로그에서 수행하는 작업입니다. 컴파일러는 'alloca()'를 프롤로그에있는 동일한 명령어로 변환해야하며 함수 호출이 필요하지 않습니다. 그렇지 않으면 인라인 어셈블리를보십시오. –

+0

@DavidHeffernan - 존재합니다, 틀렸어. – RbMm

답변

2

alloca는 부분적으로 내장 함수이며 컴파일러에서 구현됩니다. 내부적으로는 스택에서 이동 보호 페이지를 사용하기 위해 _alloca_probe_16 (x86의 경우) 또는 __chkstk (x64)을 호출합니다. 이 기능의 구현은 VC 하위 폴더 (exacly는 VC 버전에 의존)에서 찾을 수있는 alloca16.objchkstk.obj에 있습니다.이 obj를 링크 프로세스에 추가하거나 먼저 lib로 변환 할 수도 있습니다. 또한 최신 WDK libs와에 - (ntdll.lib와 혼동하지) ntdllp.lib 존재 - 그것은 또한 구현 (ntdll.dll 86 수출 _chkstk()와 __chkstk (64 용)) 자세한 내용에 다시


에 대한 모든 필요를 포함 :

당신이 SRC 코드에

alloca(cb) CL 컴파일러를 쓰기 86에서 생성

mov eax,cb 
call _alloca_probe_16 ; do actual stack allocation and probe 

및 x64 버전

mov   ecx,eax 
add   rcx,0Fh 
cmp   rcx,rax 
ja   @@0 
mov   rcx,0FFFFFFFFFFFFFF0h 
@@0: 
and   rcx,0FFFFFFFFFFFFFFF0h 
mov   rax,rcx 
call  __chkstk ; probe only 
sub   rsp,rax ; actual stack allocation 

그래서 _alloca_probe_16 및/또는 __chkstk에서어딘가에 구현해야하거나 링크 오류가 발생했습니다 - 확인되지 않은 외부 기호를.

최신 WDK 빌드에이 구현을 포함하고있는 ntdllp.lib (약 p - 아니요, ntdll.lib 참고)이 있습니다. 이 경우 귀하의 PE 수입 될 것 __chkstk 또는 ntdll.dll에서 _alloca_probe (이 기능이 얼마나 최소 XP에서 내 보낸 - 모두이 기능은 동일한 코드, 단순히 별명 포인트입니다) 또 다른 솔루션

-VC 폴더가 alloca16.objchkstk.obj을 찾을 수 있습니다 -이 obj를 링크 입력으로 사용하거나 단일 lib 파일에서 alloca16.obj + chkstk.obj을 병합 할 수 있습니다. 이 경우 귀하의 체육 아무것도 가져올 수 없습니다.

+0

이고 무엇이 흥미롭지 않습니까? – RbMm

1

스택에 대한 할당이 (일반적으로) 아키텍처 독립적이기 때문에 아키텍처에 의존하지 않아도됩니다. https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

하는 당신은 아주 간단 같은 것을 써서 : 당신이 C99을 사용하는 경우

당신은 가변 길이 배열을 사용하여이 작업을 수행하는 표준 방법이

char mybuffer[my_size]; 

을 그리고있을 것이다 스택에 할당됩니다.

+0

만약'my_size' * unknown *과 컴파일 시간이 있다면? 이것은 해결책이 아닙니다 * – RbMm

+0

@ RBM 잘, VLAs는 해당 시나리오를 위해 명시 적으로 설계되었습니다 –

+0

@RbMm : 이것이 가변 길이 배열입니다. C99 컴파일러가 있으면이 솔루션입니다. 대부분의 Windows 컴파일러는 그렇지 않습니다. –

1

alloca은 스택 포인터를 조작하기 때문에 "실제"함수가 아니며 "컴파일러 내장"입니다.어셈블리 언어에 alloca을 사용하는 함수를 컴파일하는 경우 이되어야 call alloca이 아닌 sub esp, NNN으로 직접 변환됩니다. (sub esp, NNN 외에도 함수 외에도 함수가 무엇인지, 일반적으로 정의되어있는 곳을 찾아야하며, 대체 할 수 있도록 응용 프로그램을 준비해야합니다. 이미 점프하고 있습니다. NTDLL 아무것도 사용하지하는 특이한 농구의 모든 종류를 통해,이 하나 더 있습니다.)

당신이call alloca없이 sub esp, NNN를 참조 할 경우에, 그것은 당신의 컴파일러가 alloca의 가짜 구현을 가지고 있다는 것을 의미 할 가능성이 높다 즉, 이 아니고 스택에서 할당 된 메모리를 제공하는이며, 전혀 사용하지 않아야합니다.

+2

스택 포인터를 조정하는 것 외에도, 함수 몸체 내에'alloca' 또는 VLA를 사용하면 컴파일러는 'prop ebp, mov ebp, esp, sub esp, NNN' ....'mov esp, ebp; pop ebp'와 같은 긴 프롤로그와 에필로그를 사용하기 위해'sub esp, NNN' 대신' 추가 esp, NNN' –

+0

우리는 ckeck 스택 할당을 필요로합니다. -'CL'은 이미 "컴파일러 내장"이 아닌'__chkstk'를 호출합니다. - 스택의 가드 페이지를 잊어 버렸습니다. – RbMm

+0

@RbMm 편집 참조. – zwol