Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

If i use ZwTerminateProcess in the creation callback, what will happen to the rest of callbacks?

david_mk85david_mk85 Member Posts: 35
edited September 19 in NTDEV

Lets say i am using the old process creation callback (non ex).

Now in this callback, i check certain conditions, and in some cases i terminate the process to disallow it from executing (since we cant just access deny its status, like in the case of Ex Callbacks)

To do so i get a handle to the process using OpOpenObjectByPointer, passing the EPROCESS that i got from PsLookupProcessByProcessID, and then i use ZwTerminateProcess.

My question is, will this method ever cause any problems? What will happen to rest of the callbacks? does windows understand that after i terminate it, it shouldn't call any other callbacks?

Comments

  • david_mk85david_mk85 Member Posts: 35

    Also, is there any other easier and more standard solution to terminating the process in the old creation callback? (lets assume you cant use the Ex callbacks, and we are using WDM)

  • Don_BurnDon_Burn Member - All Emails Posts: 1,747

    Your proposed approach will not work since ZwTerminateProcess will return an error that the process does not exist. The process at the time of callback is being created but is not fully formed, so you will not get the result you need. Why are you not using PsSetCreateProcessNotifyRoutineEx? It has been around for quite a long time. Approaches to killing a process in the callback before the Ex versions are all hacks, sometimes needed but never desirable.

  • david_mk85david_mk85 Member Posts: 35
    edited September 19

    @Don_Burn said:
    Your proposed approach will not work since ZwTerminateProcess will return an error that the process does not exist. The process at the time of callback is being created but is not fully formed, so you will not get the result you need. Why are you not using PsSetCreateProcessNotifyRoutineEx? It has been around for quite a long time. Approaches to killing a process in the callback before the Ex versions are all hacks, sometimes needed but never desirable.

    But it does work, i tested it from windows xp/2003 to windows 10, it will absolutely work, you can give it a try yourself. I just wanted to make sure if i need to do anything else or not. Now that i am thinking about it, multiple process creation callbacks will not have any issues either because in my systems that i am testing there are obviously already many process creation callbacks, and i suppose windows understands that when i terminate a process it doesnt call other callbacks.

    Just get a handle to the process and ZwTerminateProcess it, and you will see that i works, in all windows versions. (at least in more than 15 systems that i tested)

    I need to implement this because i need to support pre vista systems as well, in newer systems i call the Ex callback.

  • Don_BurnDon_Burn Member - All Emails Posts: 1,747

    There are at least four different paths through process creation that can invoke the callback. Bottom line, is if you do anything but the most normal of paths your approach will fail. I did test this extensively years ago when XP was the "new" desktop OS, you have tested the most common creation path, try things like forking a process, and be ready for a surprise.

  • david_mk85david_mk85 Member Posts: 35

    @Don_Burn said:
    There are at least four different paths through process creation that can invoke the callback. Bottom line, is if you do anything but the most normal of paths your approach will fail. I did test this extensively years ago when XP was the "new" desktop OS, you have tested the most common creation path, try things like forking a process, and be ready for a surprise.

    Interesting. So one path i assume is the normal creation path which a user simply double clicks on an executable or a process calls CreateProcess with the most default arguments.

    So what are the other three other paths, and which of them will bypass my method?
    Isn't forking a linux thing? i didn't know you can fork in Windows as well, even if it is possible, I am not sure if its very common either. The only method that i have been using is simply call CreateProcess or use System.

    Also, when you say fail, do you mean getting a BSOD, or simply ZwTerminateProcess failing? because i am OK with it to fail in very rare situations, but getting a BSOD is a no no for me.

  • david_mk85david_mk85 Member Posts: 35

    @Don_Burn said:
    There are at least four different paths through process creation that can invoke the callback. Bottom line, is if you do anything but the most normal of paths your approach will fail. I did test this extensively years ago when XP was the "new" desktop OS, you have tested the most common creation path, try things like forking a process, and be ready for a surprise.

    Hmmm Interesting. So one path i assume is the normal creation path which a user simply double clicks on an executable or a process calls CreateProcess with the most default arguments.

    So what are the other three other paths, and which of them will bypass my method?
    Isn't forking a linux thing? i didn't know you can fork in Windows as well, even if it is possible, I am not sure if its very common either. The only method that i have been using is simply call CreateProcess or use System.

    Also, when you say fail, do you mean getting a BSOD, or simply ZwTerminateProcess failing? because i am OK with it to fail in very rare situations, but getting a BSOD is a no no for me.

  • Don_BurnDon_Burn Member - All Emails Posts: 1,747

    I did this work many years ago for a client. On some cases with fork you kill the creating process not the one being created. Most of the other failures are that you get an error that the process does not exist.

  • david_mk85david_mk85 Member Posts: 35

    @Don_Burn said:
    I did this work many years ago for a client. On some cases with fork you kill the creating process not the one being created. Most of the other failures are that you get an error that the process does not exist.

    But fork doesn't even exist on Windows?

    https://stackoverflow.com/questions/4243880/substitute-for-forking-in-windows

    Based on the answer to that questions, it only exist on high-end versions of Windows, which doesn't concern me since i use Ex on Vista+, i only use non Ex callback on pre vista right now.

  • Don_BurnDon_Burn Member - All Emails Posts: 1,747

    Fork does exist in Windows since NT 3.1 The underlying NtCreateProcess has a lot of options. If you are going to be mucking at the level you are attempting find a copy of Windows NT/2000 Native API Reference by Gary Nebbett. If you cannot handle every option in that call, then you have not done things correctly.

  • david_mk85david_mk85 Member Posts: 35

    @Don_Burn said:
    There are at least four different paths through process creation that can invoke the callback. Bottom line, is if you do anything but the most normal of paths your approach will fail. I did test this extensively years ago when XP was the "new" desktop OS, you have tested the most common creation path, try things like forking a process, and be ready for a surprise.

    Interesting. So one path i assume is the normal creation path which a user simply double clicks on an executable or a process calls CreateProcess with the most default arguments.

    So what are the other three other paths, and which of them will bypass my method?
    Isn't forking a linux thing? i didn't know you can fork in Windows as well, even if it is possible, I am not sure if its very common either. The only method that i have been using is simply call CreateProcess or use System.

    Also, when you say fail, do you mean getting a BSOD, or simply ZwTerminateProcess failing? because i am OK with it to fail in very rare situations, but getting a BSOD is a no no for me.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,704
    edited September 24

    Yes, fork does exist… if not in name, in function. So… what Mr. @Don_Burn said is entirely correct.

    OTOH… you need this just for Win 7? Go ahead doing what you’re doing, and people who are running Win7 get what they get. After all, they’re running OS code that’s more than 10 years old and no longer maintained, so they don’t much care anyhow. (OK, that last part was sarcasm, so don’t … you know… flood me with replies — But the recommendation to just do what you want in Win7 and “they get what they get” was sincere).

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Dejan_MaksimovicDejan_Maksimovic Member - All Emails Posts: 450
    via Email
    OT, but for the visually impaired Win7 is the last usable Windows. Our
    center for the visually impaired is mostly on XP for the same reason.

    And if not for Dark Mode, I would have left Windows development a few years
    ago.

    It is not just caring, a lot is necessity.

    Kind regards, Dejan.
    https://www.alfasp.com

    OTOH… you need this just for Win 7? Go ahead doing what you’re doing, and
  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,704

    Didn’t I just write that was sarcasm, and don’t flood me with replies?

    Peter Viscarola
    OSR
    @OSRDrivers

  • Dejan_MaksimovicDejan_Maksimovic Member - All Emails Posts: 450
    via Email
    Actually, that part did not appear in the emails.

    Kind regards, Dejan.
    https://www.alfasp.com

    Didn’t I just write that was sarcasm, and don’t flood me with replies?
  • Don_BurnDon_Burn Member - All Emails Posts: 1,747

    On the what happens to the callback it depends on the type of process creation one does, i.e. CreateProcesss, the windows fork capability, etc. The OP needs to be trying every combination of ZwCreateProcess to understand this stuff, and expect to need to walk through the assembly code of the ZwCreateProcess to understand what is happening. Do not trust ReactOS on this it has bugs that cause it to act differently than Windows.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,704

    Do not trust ReactOS

    This is true as a general statement. Not just in the specific case Mr. Burn cites.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • MBond2MBond2 Member Posts: 369

    If I only had a penny for every bug & security issue caused by handle inheritance I would be wealthy.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,704

    every bug & security issue caused by handle inheritance

    Yup. This. And, you know, I honestly don’t even understand why this is a thing. Seriously, can someone explain to me, like I was six years old, what problem handle inheritance solves that can be solved otherwise? I don’t get it. And I’m sick of programming around weird edge cases it can cause.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • MBond2MBond2 Member Posts: 369

    Its main purpose is to provide automatic redirection of the standard input and standard output (and standard error) streams. That's all well and good, but a change to the console subsystem design could have achieved the same

    The secondary purpose is to pass otherwise unfindable / inaccessible synchronization or file mapping objects between a parent and child process. This is valid in some sense because object name squatting is a legitimate security issue and ACLs are useless to prevent this since the minimum granularity is a whole security principal - which can be running many processes. I'm not aware of any better way to do that then handle inheritance, but it is a small class of programs that employ this pattern and they should all be legacy and obsolete

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,704

    Thank you Mr @MBond2

    The secondary purpose is to pass otherwise unfindable / inaccessible synchronization or file mapping objects

    Yeah… that’s pretty outdated, as you say. We don’t share object instances, we share object names, and communicate them among processes via secure channels.

    they should all be legacy and obsolete

    Agreed. Thank you again.

    You know, I once suggested (long ago) in a meeting that the code to duplicate processes be removed from the OS. This happened just after support for the Posix Subsystem was removed from Windows, which would have been a great excuse. Not one person on the core team agreed that this was a good idea. Most everyone was silent, except the guy who owned the Memory Manager who dismissed it with “We can’t do that” for reasons of compatibility.

    Compat has been a great thing for Windows, but it has often been taken too far and been an excuse for not innovating. The entire I/O Subsystem has lacked innovation for years in the name of carefully maintained compatibility. The truth is, it’s super hard and risky work to champion changes, communicate these to the installed base, and get buy-in to make breaking innovations (because, unlike Linux, that would be what’s required in the Windows world). So, why do it? Fucking up a bunch of ancient drivers in the field will get you sent to Siberia. But ensuring nothing changes — including nothing improving — and that everything stays running will get you promoted to Partner Architect.

    Sad but true. Sorry… on one of my many hot-button tangents…

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,109

    Compat has been a great thing for Windows, but it has often been taken too far...

    OMG, you're likely to trigger my irate rant on the boneheaded decisions regarding GetVersion and friends. Rarely have I encountered such API stupidity.

    On the other hand, it's possible to go to far the other way as well. When Apple arbitrarily dropped support for 32-bit apps in MacOS 11, that actually changed my decision on my next laptop. My primary home laptop is now an LG Gram 17 running Linux.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • MBond2MBond2 Member Posts: 369

    I might be more sympathetic, except that I developed new code last year with EBCDIC and BCD encodings.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,109

    Interesting; I did a user-mode project last year that had to read and write EBCDIC. The spec was still based on "tape marks". Some things never change.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • MBond2MBond2 Member Posts: 369

    The IBM technology from the 1960's is still alive and well. It was good enough to fly to the moon and in my industry (banking and brokerage) it has never been supplanted

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Internals & Software Drivers 15 November 2021 Live, Online
Writing WDF Drivers 24 January 2022 Live, Online
Developing Minifilters 7 February 2022 Live, Online
Kernel Debugging 21 March 2022 Live, Online