Hola Lambda,
Sugerencias:
1-¿has probado a hacer que te imprima la matriz M3 desde dentro de la función para comprobar que la multiplicación está bien antes de asignársela a M2?
2-si has comprobado 1, ¿has comprobado a mirar si la matriz M2 antes de salir de la función tiene el resultado de la multiplicación?
3- IMPORTANTE!! ¿M3 y M2 tienen las mismas dimensiones?
4.- Intenta probar a que la función te devuelva directamente M3, o un puntero a ella como te sea más fácil para luego poder recogerlo en tu código.
Haciendo:
Matriz multiplica (Matriz *M1, Matriz *M2){
//tu código
return M3;
}
o haciendo:
Matriz* multiplica (Matriz *M1, Matriz *M2){
//tu código
return (&M3);
}
5.- Revisa los whiles, sus condiciones de parada y la reutilización de las variables con las que recorres las matrices. Un consejo: mejor utiliza los bucles for.
Espero haberte ayudado en algo

.
Saludos!