Muchas veces se usa NOP
para alinear direcciones de instrucciones. Esto suele aparecer, por ejemplo, al escribir Shellcode para explotar desbordamiento del búfer o vulnerabilidad de la cadena de formato .
Supongamos que tiene un salto relativo a 100 bytes hacia adelante y realice algunas modificaciones al código. Lo más probable es que sus modificaciones arruinen la dirección del objetivo de salto y, como tal, también tendría que cambiar el salto relativo antes mencionado. Aquí, puede agregar NOP
s para adelantar la dirección de destino. Si tiene varios NOP
s entre la dirección de destino y la instrucción de salto, puede eliminar el NOP
s para tirar de la dirección de destino hacia atrás.
Esto no sería un problema si está trabajando con un ensamblador que admite etiquetas. Simplemente puede hacer JXX someLabel
(donde JXX es un salto condicional) y el ensamblador reemplazará el someLabel
con la dirección de esa etiqueta. Sin embargo, si simplemente modifica el código de máquina ensamblado (los códigos de operación reales) a mano (como sucede a veces al escribir shellcode), también tiene que cambiar la instrucción de salto manualmente. O lo modificas, o luego mueves la dirección del código de destino usando NOP
s.
Otro caso de uso para la instrucción NOP
sería algo denominado trineo NOP . En esencia, la idea es crear un conjunto suficientemente grande de instrucciones que no causen efectos secundarios (como NOP
o incrementando y luego disminuyendo un registro) pero incrementando el puntero de la instrucción. Esto es útil, por ejemplo, cuando uno quiere saltar a un determinado fragmento de código cuya dirección no se conoce. El truco es colocar el dicho trineo NOP frente al código objetivo y luego saltar a algún lugar al dicho trineo. Lo que sucede es que la ejecución continúa esperanzadamente desde la matriz que no tiene efectos secundarios y atraviesa la instrucción por instrucción hacia adelante hasta que llega a la pieza de código deseada. Esta técnica se usa comúnmente en las vulnerabilidades de desbordamiento de búfer mencionadas anteriormente y, especialmente, para contrarrestar medidas de seguridad como ASLR .
Otro uso particular para la instrucción NOP
es cuando uno está modificando el código de algún programa. Por ejemplo, puede reemplazar partes de saltos condicionales con NOP
sy, como tal, evitar la condición. Este es un método de uso frecuente cuando " craqueo " protege el software. En la forma más simple, solo se trata de eliminar el código de ensamblaje para la línea de código if(genuineCopy) ...
y reemplazar las instrucciones con NOP
s y ... ¡Voilà! No se realizan comprobaciones y no funciona la copia original.
Tenga en cuenta que, en esencia, ambos ejemplos de shellcode y cracking hacen lo mismo; modifique el código existente sin actualizar las direcciones relativas de las operaciones que dependen del direccionamiento relativo.