2009-10-09 4 views
3

어셈블러, C++ 및 PE 파일 작동 방식에 대해 더 배우는 방법으로 exe packer/protector를 코딩하려고합니다. 나는 현재 EP를 포함하고있는 섹션이 키와 XOR되고, 새로운 섹션이 나의 암호 해독 코드를 포함하도록 생성되도록하고있다. 해독 후 원본 EP에 JMP를 시도 할 때를 제외하고 모든 것이 훌륭합니다.절대 주소 (연산 코드)에 대한 JMP

DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint; 
// -- snip -- // 
    crypted.put(0xE9); 
crypted.write((char*)&orginalEntryPoint, sizeof(DWORD)); 

을하지만 대신 엔트리 포인트로 점프의, 올리 디버그이 코드가 분해 있음을 보여줍니다 : 기본적으로

나는 이렇게

00404030 .-E9 00100000 JMP 00405035 ; should be 00401000 =[ 

내가하려고 할 때 수동으로 변경하기 olly 새로운 opcode가

00404030 -E9 CBCFFFFF JMP crypted.00401000 

으로 표시됩니다. 0xCBCFFFFF는 어디에서 왔습니까? C++ 측에서 어떻게 생성할까요?

답변

5

나는 E9이 상대 점프를위한 opcode라고 생각한다 : 그 피연산자는 다음 명령의 시작에서 플러스 또는 마이너스 점프 될 상대 거리를 지정한다.

피연산자가 절대 주소를 지정하려면 다른 opcode가 필요합니다.

+0

E9의 대체품은 무엇입니까? –

+0

@Chris : 검색시 도움이 될 수 있습니다. http://ref.x86asm.net/ – fvu

+0

점프는 대개 상대적입니다. 절대 far 주소로 점프하기위한 opcode 'EA'와 간접 주소로 점프하기위한 opcode (피연산자가 점프 할 주소를 포함하는 메모리 위치를 지정하는 곳)가 있습니다. – ChrisW

14

당신은 사용할 수 있습니다

push DESTINATION_VA 
ret 

또는

mov eax,DESTINATION_VA 
jmp eax 

상대 E9의 JMP 인코딩은 다음과 같이 사용됩니다 : 당신이있는 경우

CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)]) 

푸시 + RET는 VA 최적의 솔루션입니다 주소와 이미지가 이전되지 않았습니다.

+1

저를 구해줘서 고마워요! – Gizmo

6

절대 간접 점프를위한 opcode는 FF + 4 바이트 주소입니다. 이것은 데이터에 저장된 주소의 jumptables에 가장 자주 사용됩니다.

예상 주소에로드되지 않을 때 절대 주소는 재배치가 필요하므로 상대 주소가 일반적으로 선호됩니다. 상대 점프에 대한 코드도 2 바이트 작아집니다.

Intel 최적화 설명서에 따르면 호출 및 ret가 쌍으로 사용될 것으로 예상되므로 응답 2에서 제안 된 호출이없는 경우에는 "성능 저하"가 발생합니다.

또한 코드가 컴파일러가 가정 한 동일한 주소로로드되지 않은 경우 ret가 프로그램을 중단시킬 수 있습니다. 상대 주소를 계산하는 것이 더 안전합니다.

+3

아마도 FF 25 4byte를 의미합니다.FF 4 바이트는 전혀 이해가되지 않습니다. – Laie

+0

@Laie 여전히 'FF'가 opcode이고 니모닉이'jmp'이므로 알 수 있습니다. 둘 다 절대 간접적으로 점프하기 때문에 'FF/4'또는 'FF/5'가 될 수 있습니다. 하나는 가까운 거리이고 다른 하나는 먼 거리입니다. 하지만 그렇습니다. 'FF 25 aa bb cc dd'는 기계 코드에서 'FF/4'(더 일반적인 두 가지)를 관찰하는 방법입니다. –