Solved

Sending a command to console (cmd.exe)

Posted on 2010-08-22
15
838 Views
Last Modified: 2012-05-10
Hello,

I am sending a command to an open console (cmd.exe) via
AttachConsole()
...
fprintf(stdout,"dir");

The "dir" appears inside the console, however, when I manually press enter on the console window, the "dir" is not recognized as a command, it basicly executes the last manually entered command...

What should I do?

Tank You
0
Comment
Question by:hlienert
  • 6
  • 6
  • 3
15 Comments
 
LVL 40

Expert Comment

by:evilrix
ID: 33495192
>> What should I do?
You can't just print something to the console and expect it to be recongnised as a command. Execute it using the system function instead.

http://www.cplusplus.com/reference/clibrary/cstdlib/system/
fprintf(stdout,"dir"); // < --print it

system("dir"); // <-- execute it

Open in new window

0
 
LVL 8

Expert Comment

by:Anthony2000
ID: 33495376
I agree with evilrix, but if you really want to do it the way you describe....

I found this article that appears to do something like what you are trying to do. I unfortunately don't have the proper version of Microsoft's tools to try it.

http://www.devx.com/dotnet/Article/7914/0/page/5

Take a look.


0
 

Author Comment

by:hlienert
ID: 33497258
Hi!

I did that:
fprintf(stdout,"dir"); // < --print it
system("dir"); // <-- execute it

but somehow it brings out a different output than when I type the command.
When I type it, it brings the list of files in the current folder.
When I "execute" it, it says the Volume Information of the current drive...

@Anthony2000: I am not so sure what u mean...
0
 
LVL 8

Expert Comment

by:Anthony2000
ID: 33497734
Did you try this for an example to compare:

type this dir c:\ in the console

then do:

system("dir c:\\");

You need the double backslash otherwise the compiler will told that you are trying to include the " in the message and you will get a compiler error.

Do both of these give you the same results?


0
 
LVL 8

Expert Comment

by:Anthony2000
ID: 33497739
I forgot to mention, when the system() function is executed, the current directory may not be the same as the one that the console has. So, for a test, if you tell the dir command what folder you want a listing of, the output should then be the same.

Do you still need to send the command to an already open console window? This is why I included the link above.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33498573
>> but somehow it brings out a different output than when I type the command.

As Anthony2000 eludes, unless you provide a path to dir it will give you a listing of the current working directory (whatever that is). You have two solutions...

-- where path is the directory you wish to list
1. system("dir ");
2. system("cd ; dir");
0
 

Author Comment

by:hlienert
ID: 33498633
Well, I am actually running a dll. If you type a certain keyword on your console + a trigger, this keyword will be replaced by a user-predifined command that is ment to be displayed and executed.
The displaying part works fine via fprintf
The execution gives out garbage. I tried with different commands (dir, cd..) it always brings some funny characters on the console.
For instance, if I use the system("cd..") command it only displays "cd..". If I manually press enter on the console, it brings out next line:
>cd.. ¿¿funden werden.¿¿ist entweder falsch geschrieben oder¿¿konnte nicht ge

It is german, it basicly trying to tell me my command is either misspelled or could not be found. But the words are scrammbled and misplaced.

Using c++ and WIndows 7
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 40

Expert Comment

by:evilrix
ID: 33498652
Some code would be nice -- all of it that is relevant :)
0
 

Author Comment

by:hlienert
ID: 33498749
I solved the problem using the SendKeys class.

But here is the code of fprintf/system approach:

int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
FreeConsole();
DWORD pid;
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap != INVALID_HANDLE_VALUE )
{
  if( Process32First( hProcessSnap, &pe32 ) )
  {
        pe32.dwSize = sizeof( PROCESSENTRY32 );
        do
        {
            CString cs_Name=pe32.szExeFile;
            cs_Name.MakeLower();
            if (cs_Name.Right(7)=="cmd.exe")
            {
                  pid=pe32.th32ProcessID;
            }

        } while( Process32Next( hProcessSnap, &pe32 ) );
        CloseHandle( hProcessSnap );
  }
}
BOOL res = AttachConsole(pid);
if(res==0) return;

lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );

fprintf(stdout,text_plain);
system("cd..");
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33498810
Where is text_plain ever initialised? That code will just output garbage.

The system command just does a "cd.." what about the dir?

Incidentally, you could (and this would have been a better solution that system) also used the popen function to do this.
http://msdn.microsoft.com/en-us/library/z0kc8e3z(VS.80).aspx
0
 

Author Comment

by:hlienert
ID: 33498829
Yes, sorry, I slightly modified the code.
The "dir" was just an example, just as "cd..." is.
Just see the last 2 lines like this:

CString text_plain="cd...";
fprintf(stdout,text_plain);
system(text_plain);

0
 
LVL 40

Accepted Solution

by:
evilrix earned 500 total points
ID: 33498839
Ok, I am guessing you're building this as a Unicode application, in which case the CString will be wide and not narrow. Try this instead...

char const text_plain[] = "cd ; dir"; // where  is the directory you wish to list
fprintf(stdout,text_plain);
system(text_plain);
0
 

Author Comment

by:hlienert
ID: 33498941
Yes, that seemed to do the trick.

I will still use the SendKeys now, but will accept your answer.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33499057
>> Yes, that seemed to do the trick.
Great - does it make sense to you why my change worked? If not I am happy to elaborate.
0
 

Author Comment

by:hlienert
ID: 33499984
Yes, it did.
Funny thing is, my project settings are multi-byte.
But still, I guess I was setting the wrong conversion while getting text_plain from my database.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now