You don't need to emulate the hardware to see a program's output, you can just look at your screen. There is little point in hiding the output of a program from the user who's running it so I don't see that as the point (if one cannot observe the output of a program, it is of little utility).
Which instructions a given program executes depends on the inputs to said program. For any given input, most programs only execute a tiny portion of their code. Therefore, in order to completely reverse engineer a program, you would have to observe the output for all possible inputs. This is almost certainly intractable for any sufficiently complex program. Suppose you wrote a program to iterate over all possible inputs observing the output of each input; things get interesting if you liken this to the halting problem.