Je suis sur le point d'apprendre comment Sysenter sur X86 fonctionne. Et j'ai créé une application de console simple sur la plate-forme X86, qui devrait appeler la fonction NTWriteVirtualMemory manuellement dans l'assemblage en ligne.
J'ai commencé avec ce code ici, mais il semble que le compilateur ne comprenne pas l'opcode "Sysenter" alors j'ai décidé de _emit code> avec les octets pour Sysenter. (Je dois peut-être modifier quelque chose dans mes paramètres de projet?) Il compile, mais quand il est sur le point d'appeler la fonction Visual Studio me donne une erreur que mon Quelqu'un a des connaissances comment faire correctement? P> RET est une instruction illégale lors de l'exécution et que le programme s'arrête. P>
#include <windows.h>
#include <iostream>
__declspec(naked) void __KiFastSystemCall()
{
__asm
{
mov edx, esp
// need to emit "sysenter" because of syntaxerrors, "Opcode"; "newline"
_emit 0x0F
_emit 0x34
ret // illegal instructiona after execute?
}
}
void Test_NtWriteVirtualMemory(HANDLE hProcess, PVOID BaseAddress, PVOID Buffer, SIZE_T sizeToWrite, SIZE_T* NumberOfBytesWritten)
{
__asm
{
push NumberOfBytesWritten
push sizeToWrite
push Buffer
push BaseAddress
push hProcess
mov eax, 0x3A // Syscall ID NtWriteVirtualMemory in Windows10
mov edx, __KiFastSystemCall
call edx
add esp, 0x14 // 5 push * 4 bytes 20 dec
retn
}
}
void Test_NtWriteVirtualMemory(HANDLE hProcess, PVOID BaseAddress, PVOID Buffer, SIZE_T sizeToWrite, SIZE_T* NumberOfBytesWritten)
{
__asm
{
push NumberOfBytesWritten
push sizeToWrite
push Buffer
push BaseAddress
push hProcess
mov eax, 0x3a // Syscall ID NtWriteVirtualMemory in Windows10
mov edx, 0x76F88E00
call edx
ret 0x14
}
}
int main()
{
std::cout << "Test Hello World\n";
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetProcessId("MyGame.exe"));
if (hProcess == NULL)
return false;
DWORD TestAddress = 0x87A0B4; // harcoded
DWORD TestValue = 4;
Test_NtWriteVirtualMemory(hProcess, (PVOID)TestAddress, (PVOID)TestValue, sizeof(DWORD), NULL);
CloseHandle(hProcess);
return 0;
}
3 Réponses :
Étant donné que vous avez une instruction illégale sur l'instruction RET plutôt que sur l'instruction Sysenter, vous savez que l'instruction Sysenter a été décodée correctement par la CPU. Votre appel est entré en mode noyau, mais le noyau n'aimait pas l'invocation de votre système d'appel système. P>
Il s'agissait probablement de l'espace utilisateur pour aider à enregistrer certains registres car Je ne spéculerais que comme le problème, mais j'enveloppe la porte SysCall dans un autre appel de fonction semble mal à mes yeux. Comme je l'ai dit dans les commentaires, ne faites pas cela parce que les numéros SysCall peuvent changer sur vous. P>
Sous Linux, les processus 32 bits appellent à travers la VDSO (une bibliothèque injectée dans leur espace d'adresses par le noyau) pour obtenir l'instruction optimale d'appel système, utilisée d'une manière qui correspond à ce que veut le noyau. ( Peut-être que si vous voulez jouer avec cette instruction, vous feriez mieux d'écrire un système d'exploitation Toy. P>
Désolé, ce n'est pas une tonne de réponse, mais ce n'est pas complètement déraisonnable. P> sysenter code> est très minime. Vérifiez le pointeur de la pile après avoir revenu du noyau lorsque vous vous trouvez à sens unique avant de laisser
res code> exécuter. P>
sysenter code> ne conserve pas le pointeur de pile afin que l'espace utilisateur doit aider.) p>
Merci pour l'information, mais qui peut me montrer comment le faire correctement alors ??
x86-64 gnu / linux a une utilisation glibc syscall code> directement, indirectant uniquement via la VDSO pour "Appels système" qui n'ont pas besoin d'entrer dans le noyau. (
getpid code>,
clock_gettime code>, etc.) 32 bits x86 glibc indirecte via la VDSO pour que tout pour permettre à "la bibliothèque" du noyau, faire le côté de l'espace utilisateur optimal de la Sysenter danse ou utilisez 32 bits
syscall code> sur Old AMD ou utilisez
int 0x80 code>. blog.packagecloud.io / fre / 2016/04/05 / ... Donc, je pense que vous avez inversé "x86" et "x64" dans votre 3ème paragraphe.
@Petercordes: N'hésitez pas à éditer. C'est une réponse cachée de toute façon que OP ne veut que une réponse de Windows.
Avez-vous une version forte> 32 bits forte> de Windows? P>
Ainsi, afin d'utiliser Windows 64 bit utilise Par exemple, si vous intégrez l'instruction code> SYSCALL code>, le premier paramètre de la pile (le cas échéant) doit être à Le mode de compatibilité 32 bits SysCall Convention est également différent, vous devez définir les deux 1 sup> Je n'ai pas de source définitive pour cela, il ne s'agit que de zéro sur ma version em> de Windows et qu'il fait 2 sup> i.e. a sysenter code> était le "successeur" de
int 2eh code> et introduit lors de l'ère Windows XP.
Les versions 64 bits de Windows ne l'utilisent pas, en fait, a été supprimée forte> depuis: p>
sysenter code> et
sysret code> est illégal en mode long dans une CPU AMD (indépendamment du mode de compatibilité). LI>
iA32_sysenter_cs code> MSR est laissé à zéro par une version 64 bits de Windows 1 sup>.
Cela provoquera une défaillance #gp lors de l'exécution de sysenter code>.
Si vous avez une étape unique via votre __ kifastsystemcall code> Vous devez voir le débogueur Attraper une exception avec le code 0xc0000005 em> lors de l'exécution
sysenter code>. Li>.
ol>
sysenter code>, vous devez avoir une version réelle de Windows 32 bits.
L'exécution d'un programme 32 bits sur une version 64 bits de Windows ne fonctionnera pas, c'est le mode de compatibilité (fait via les machines WOW64).
Si, outre avoir une version de Windows de 64 bits, vous avez également une CPU AMD, alors cela ne fonctionnera pas à la double fois. P>
syscall code> pour un programme 64 bits ou un appel indirect sur le champ
WOW32RESERVÉ code> du champ Teb em> 2 sup>, vous devez utiliser celles-ci.
Méfiez-vous que la convention d'appel système 64 bits est légèrement différente de la part habituelle: elle suppose particulièrement le syscall code> est dans une fonction de son propre em>, il s'attend ainsi aux paramètres la pile à décaler par 8.
De plus, le premier paramètre doit être dans
r10 code>, pas
rcx code>. P>
RSP + 28H CODE> et non sur
RSP + 20h code>. P>
EAX code> et
ECX code> sur des valeurs spécifiques.
Je n'ai pas creusé ce que ECX code> est utilisé, mais il peut être lié à une optimisation appelée
Turbo Thunks code>
et doit être défini sur une valeur spécifique.
Notez que, alors que les numéros SysCall sont très volatils, Turbo Thunks sont encore plus parce qu'ils peuvent être désactivés par l'administrateur. P>
sysenter code> défaut . p>
appel dword [fs: 0c0h] code>, cela pointera sur un code qui passera à un descripteur de porte pour un segment de code 64 bits qui exécutera à son tour un
syscall code> p>
Mes Windows est une version 64 bits, ma console est 32 bit et mon jeu est trop 32 bits. J'ai essayé de remplacer appel edx code> avec l'appel
appel DWORD PTR FS: [0xc0] code>. Il se déroule mais me gagne une violation d'accès sur la fonction ..
Prenez votre version 32 bits de ntdll.dll i> et désassemblable NTWriteVirtualMemory code>, vous devez voir quelles valeurs à mettre dans Tous les registres b> qui sont nécessaires ( Cela inclut
edx code>,
ex code> et
ECX code>, dépend de la version de Windows).
merci je l'ai fait, voici une image des octets [link] imgur.com/a/v6fv1a8 . Je fais tout cette assemblée similaire, mais cela ne compile pas vraiment -> "Violation d'accès". J'ai ajouté le code ci-dessus que j'ai utilisé.
Vous n'avez pas appuyé sur l'adresse de retour, ntwritevirtualmemory code> a l'adresse de retour de l'appelant en haut de la pile lors de la saisie. De plus, je ne suis pas sûr que la codage d'une adresse fonctionne pour toutes les pistes (je ne sais pas si Windows fait ASLR sur des fichiers binaires 32 bits). Si j'étais vous, je ferais un programme simple qui appelle
ntwritevirtualmemory code> normalement, puis entrez-le en progressant dans le programme de défaillance, en vérifiant les valeurs de la pile et de l'enregistrement. Cela mettrait en évidence les divergences.
Faire des appels système dans X86 Windows est différent de X64. Vous devez spécifier la longueur correcte des arguments dans res em> sinon, vous obtiendrez des instructions illégales et / ou d'exécuter ESP. En outre, je ne vous recommande pas d'utiliser l'assemblage en ligne, l'utiliser à l'intérieur d'un. fichier ASM ou comme shellcode. p> pour faire un appel pour faire un CORRECT STRAND> X64 System Call On x64 Windows: P> mov eax, SYSCALL_INDEX
mov r10,rcx
syscall
retn
Les numéros Windows SysCall peuvent changer en fonction du niveau de correctif de la machine. S'il vous plaît ne faites pas cela.
Oui, je sais que c'est juste à des fins de test.