Citar¿cada vez que haga una shell y quiera sacar los opcode es necesario usar push y guardar en el stack todo?Eres libre de programar tu shellcode como deses, puedes hacerlo bien o puedes hacerlo mal. Es muy recomendable guardar el contexto de la pila, lo cual se hace mediante las instrucciones que mencionaste, y contrastando empíricamente tu mismo te diste cuenta que la mayoría de shellcodes siguen dicho procedimiento.
Luego respecto a lo de empujar cadenas a la pila y demás depende del tipo de función que estés utilizando y cómo reciba los parámetros si los recibe por registro no sería necesario almacenarlos en la pila.
Citar¿entonces es necesario meter en el stack todo en casos de shellcodes o será simplemente una coincidencia o una forma diferente de programar?Creo que esta duda ya te la aclaré.
Citar¿Y que pasa con los opcode "Cero" que si son necesarios?Bueno aquí no está del todo bien lo que te dice el compañero @No tienes permitido ver enlaces. Registrate o Entra a tu cuenta , realmente no pasa nada en el shellcode porque contenga null bytes (\x00). Cada escenario es un mundo paralelo, normalmente se trata de evitar dichos null bytes por el tema de que en determinadas situaciones la gente se enfrenta a una función la cual interpreta un conjunto de bytes para su propio funcionamiento interno.
Un ejemplo sería strcpy la cual interpreta dicho null byte como un terminador de cadenas y a partir del mismo cesa la ejecución de los op codes consecutivos, como consecuencia tendremos una ejecución de código arbitrario fallida. Pero no necesariamente hay que temer a dichos null bytes a diferencia de strcpy, gets() te permitiría ejecutar tu shellcode con los tan odiados null bytes.
Con esto me reitero, cada escenario es un mundo.
Un saludo