{"id":18,"date":"2007-07-15T17:19:50","date_gmt":"2007-07-15T21:19:50","guid":{"rendered":"http:\/\/www.ragestorm.net\/blogs\/?p=18"},"modified":"2007-07-17T13:14:10","modified_gmt":"2007-07-17T17:14:10","slug":"ntvdm-1","status":"publish","type":"post","link":"https:\/\/www.ragestorm.net\/blogs\/?p=18","title":{"rendered":"NTVDM #1"},"content":{"rendered":"<p>DOS is dead; and that&#8217;s a fact. But NTVDM is still a cool and handy useful tool. I guess that most of us are not satisfied with the way it works&#8230;usually the sound doesn&#8217;t work, which is a good enough cause to try the great opened source projects which simulate DOS. Anyways, a few years a go, a friend of mine wrote some piece of code which writes to 0xb800, remember this one? That&#8217;s the text mode buffer starting address. Anyways, I was wondering how come you write to this address and something appears on the screen (of course, there is the attribute and the character), mind you it&#8217;s NTVDM we are talking about. But this wasn&#8217;t the interesting part &#8211; Why sometimes your writes to this buffer works and sometimes simply not. I decided to learn the situation and see why it happens.<\/p>\n<p>So here&#8217;s what I did:<\/p>\n<p>mov ax, 0xb800<br \/>\nmov ds, ax<br \/>\nmov ax, 0x0741<br \/>\nmov [bx], ax<br \/>\nret<\/p>\n<p>Which prints a grey &#8216;a&#8217; in the top left corner, yeppi. Now if you open cmd and run the .com file of this binary you won&#8217;t see anything at all. Which is unexpected because you write to the &#8216;screen&#8217;, after all. Now, my friend only knew that whenever he runs &#8216;debug&#8217; before his program, which I just showed the important part above, then the letter &#8216;a&#8217; will be displayed. So I gave it a long thought&#8230;.    &#8230;. After that I tried the following addition to the above code (I put it before the original code):<\/p>\n<p>mov ax, 3<br \/>\nint 0x10<\/p>\n<p>This will only set the current video mode to text mode 80x25x16&#8230; And then voila, the writing worked as expected. Then I suspected that the VM monitors for int 0x10 and function #0, set mode. But it had seemed that every function will enable the writes&#8230;And I later confirmed that it is true.<\/p>\n<p>So now that I knew how to trigger the magic, I simply searched for &#8216;cd 10&#8217; (that&#8217;s int 0x10) in &#8216;debug&#8217; and found a few occurrences, which proved my friend&#8217;s experience &#8211; that after running &#8216;debug&#8217;, writing to 0xb800 would work. Of course, if you ran other programs which used int 0x10, you&#8217;re good to go as well.<\/p>\n<p>But that was only one thing of the mystery, I wanted to also understand how the writes really happens. Whether the VM monitors all instructions and checks the final effective address to see if it&#8217;s in the buffer range, or maybe the memory is specially mapped with Win32 API. Because after all, the NTVDM screen is a <em>normal<\/em> console window (not speaking of graphical modes now). Surprisingly, I found out that the solution was even simpler, a timer was issued every short interval, which called among other things to a function that copies the 0xb800 buffer to the real console screen, using some console APIs&#8230; And yes, your simulated writes really go to the virtual memory of the same address in the real NTVDM.exe process. Maybe it has a filter or something I assume, but I didn&#8217;t look for it, so I really don&#8217;t know.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>DOS is dead; and that&#8217;s a fact. But NTVDM is still a cool and handy useful tool. I guess that most of us are not satisfied with the way it works&#8230;usually the sound doesn&#8217;t work, which is a good enough cause to try the great opened source projects which simulate DOS. Anyways, a few years [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":""},"categories":[5,19,13,7],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbWKd-i","_links":{"self":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/18"}],"collection":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=18"}],"version-history":[{"count":0,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=\/wp\/v2\/posts\/18\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ragestorm.net\/blogs\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}