Bash 'printf' equivalent for command prompt? - windows

I'm looking to pipe some String input to a small C program in Windows's command prompt. In bash I could use
$ printf "AAAAA\x86\x08\x04\xed" | ./program
Essentially, I need something to escape those hexadecimal numbers in command prompt.
Is there an equivalent or similar command for printf in command prompt/powershell?
Thanks

In PowerShell, you would do it this way:
"AAAAA{0}{1}{2}{3}" -f 0x86,0x08,0x04,0xed | ./program

I recently came up with the same question myself and decided that for someone developing Windows exploits it is worth installing cygwin :)
Otherwise one could build a small C program mimicking printf's functionality:
#include <string.h>
int main(int argc, char *argv[])
{
int i;
char tmp[3];
tmp[2] = '\0';
if (argc > 1) {
for (i = 2; i < strlen(argv[1]); i += 4) {
strncpy(tmp, argv[1]+i, 2);
printf("%c", (char)strtol(tmp, NULL, 16));
}
}
else {
printf("USAGE: printf.exe SHELLCODE\n");
return 1;
}
return 0;
}
The program only handles "\xAB\xCD" strings, but it shouldn't be difficult to extend it to handle "AAAAA\xAB\xCD" strings if one needs it.

Related

Remove first line from bigfile using bash

I have a text file and want to remove the first line (header), to read the file without header into a pipeline. This seems like a trivial question that has been answered many times, but due to the size of the files I'm facing, the solutions i found so far were not working. For my test runs i used echo "$(tail -n +2 "$FILE_NAME")" > "$FILE_NAME", but running this with my a bigger file results in the following error: bash: xrealloc: cannot allocate 18446744071562067968 bytes (1679360 bytes allocated) Is there any method that edits the file in place? Loading them into the memory wont work, some of my files are up to 400 Gb in size.
Thanks for the help!
You can use code like this:
awk 'NR!=1 {print}' input_file >output file
This will send to output file all but first line. You can use this construction to do your operations:
awk 'NR!=1 {print}' input_file|operation1|operation2...
Changing your command on this way can do the work:
tail -n +2 "$FILE_NAME" > "${FILE_NAME}.new"
This will need double diskspace
Tail is reasonably efficient for this operation.
The issue is with you wanting to overwrite the original file.
Using bash "$()" to defer the creation of the output file means bash has to hold the content in memory, hence the error message. For large files you would be better off writing the output to a temporary file, then use mv to move that over the original.
When sed is used in overwrite mode it does exactly this (for anything over a few lines).
sed -i 1d "$FILE_NAME"
It runs sed with the verysimple script 1d which picks the first line (the 1 selector) and deletes it (the d command). Thanks to the in-place option -i your file will be overwritten without using an intermediate file.
Even though you do not bother with an intermediate file, sed uses his own intermediate file internally. Your disk usage will suffer up to twice the file size during this operation.
I'm just going to address the "edit the file in place" portion of the question, although it appears that was not really what you were looking for. You will find many solutions describing features that claim to do in-place editing, but usually those solutions don't actually edit the file at all. Instead, they write to a temporary file and then overwrite the original with the temporary file. (eg, sed --in-place is a common solution which writes to a temporary file). Editing the file in place is something that you almost never actually want to do, since mutating a file is dangerous. Truly, if you believe you want to edit a file in place, give it serious thought and assume that you are wrong. However, if for some reason you really do need to do it, it's probably safest to just do it:
#include <err.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
FILE * xfopen(const char *path, const char *mode);
int is_regular(int, const char *);
int
main(int argc, char **argv)
{
const char *rpath = argc > 1 ? argv[1] : "stdin";
const char *wpath = argc > 1 ? argv[1] : "stdout";
FILE *fr = argc > 1 ? xfopen(rpath, "r") : stdin;
FILE *fw = argc > 1 ? xfopen(wpath, "r+") : stdout;
char buf[BUFSIZ];
int c;
size_t rc;
off_t length = 0;
/* Discard the first line */
while( (c = getc(fr)) != EOF && c != '\n' ) {
;
}
if( c != EOF) while( (rc = fread(buf, 1, BUFSIZ, fr)) > 0) {
size_t wc;
wc = fwrite(buf, 1, rc, fw);
length += wc;
if( wc!= rc) {
break;
}
}
if( fclose(fr) ) {
err(EXIT_FAILURE, "%s", rpath);
}
if( is_regular(fileno(fw), wpath) && ftruncate(fileno(fw), length)) {
err(EXIT_FAILURE, "%s", wpath);
}
if( fclose(fw)) {
err(EXIT_FAILURE, "%s", wpath);
}
return EXIT_SUCCESS;
}
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = fopen(path, mode);
if( fp == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
int
is_regular(int fd, const char *name)
{
struct stat s;
if( fstat(fd, &s) == -1 ) {
perror(name);
exit(EXIT_FAILURE);
}
return !!(s.st_mode & S_IFREG);
}
By being explicit, it's pretty clear that you can easily lose data in the file. But if you want to avoid reading the entire file into memory, or avoid having two copies on some backing media at the same time, there's no way to avoid doing that and any solution which obscures that risk is fooling you. So making it explicit and knowing where the dangers lie is the right thing to do.
We can use the -i (in-place) option with sed to write the change back to the input file instead of printing the result to stdout:
sed -i '1d' FILE

I am trying to write a shell program to execute more than one command at a time

My Code
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
char * arg_list[3];
arg_list[0] = "ls";
arg_list[1] = "-l";
arg_list[2] = 0;
char *arg_list2[3];
arg_list2[0] = " ps";
arg_list2[1] = "-ef";
arg_list2[2] = 0;
for(int i=0;i<5;i++){ // loop will run n times (n=5)
if(fork() == 0) {
if (i == 0){
execvp("ls", arg_list);
}else if(i==1){
execvp("ps" , arg_list2);
}else if(i>1){
printf("[son] pid %d from [parent] pid %d\n",getpid(),getppid());
exit(0);
}
}
}
for(int i=0;i<5;i++) // loop will run n times (n=5)
wait(NULL);
}
ME trying to modify it
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
for(int i=0;i<5;i++){ // loop will run n times (n=5)
if(fork() == 0) {
printf("[son] pid %d from [parent] pid %d\n",getpid(),getppid());
execlp(argv[i],argv[i],argv[i+1],(char*)NULL);
exit(0);
}
}
for(int i=0;i<5;i++) // loop will run n times (n=5)
wait(NULL);
}
-- NEED GUIDANCE AND UNDERSTANDING
I am trying to make my own tiny little shell program. When I run my first code works fine, runs all commands on the command line. But I cannot know and define all commands the user might enter. So i am trying to get a base code which could run any commands single or multiple entered by user. I tried using execlp where it does not compile saying argv is not defined which is true as i don't want to specifically define it.
I am trying to make my own tiny little shell program. When I run my first code works fine, runs all commands on the command line. But I cannot know and define all commands the user might enter.
For sure.... A shell program purpose is basically:
Read user input
Execute user input
Return result of execution.
There's nothing in your code that read user input....
So i am trying to get a base code which could run any commands single or multiple entered by user.
So read user input ;-)
I tried using execlp where it does not compile saying argv is not defined which is true as i don't want to specifically define it.
For sure ... but how would GCC guessed that `argv[]̀ must be automaticallty filled with user input ?
There's nothing automatic when coding in C language. You have to manage this manually.
Also, note that argc, argv et envp are usually reserved for main() function:
main(int argc, char **argv, char **envp)
So you may use something else to build your command array.
In pseudo code, what you must implement is:
quit=0
while (quit = 0) {
command_to_run = read_user_input();
if (command_to_run == "exit") {
quit = 1;
} else {
execute(command_to_run);
}
}
Some advices:
Try to use more functions. For example, implement a fork_and_run(char **cmd) function to fork and then execute command provided by the user. Il will make your code more readable and easy to maintain.
Read carefully manpages: everything you should know (like, for example, the fact that array provided to execvp() must be NULL-terminated) is written in it.
Your debugging messages should be printed to stderr. The result of the command run must be printed to stdin, so use fprintf() instead of printf() to write to the correct stream.
I would use a #define debug(x) fprintf(stderr, x) or something similar for debugging output so that you can easily disable later ;-)

I am having a problem passing arguments to execvp using sleep and fork

I asked a really terrible question last time so I will try and do better here. I have the following code:
int main(int argc, char* argv[])
{
int forkChild;
char* argList[] = {"10","20","30"};
forkChild = fork();
if(forkChild == 0)
{
execvp("sleep",argList);
exit(0);
}
else
{
wait(NULL);
}
}
I am having trouble getting the execvp line to work. It will not sleep at all. It seems that the trouble might be because the argList array is passing strings and not integers to execvp. If I plug an integer directly into sleep it seems to work fine.
Eventually my program should be able to pass any parameter to execvp, so I am not sure why there is a problem with argument types. Is there something to this that I am not seeing?
Thanks

Empty Working Set from cmd

I want to write a cmd script to periodically empty the working set from the command prompt. For now I empty the working set in the Rammap tool from sysinternals, but that can't be run by a script.
It's probably easiest to compile something like this:
#include <iostream>
#include <windows.h>
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: min_mem <process_id>\n";
return 1;
}
HANDLE process = OpenProcess(PROCESS_SET_QUOTA, false, atoi(argv[1]));
SetProcessWorkingSetSize(process, -1, -1);
}
...and then run it in your script, something like:
mem_min 1234
...but replacing 1234 with the process ID (in decimal) of the process whose memory you want to minimize.
That said: I'd ask that this answer not be upvoted, since it's really a pretty crappy answer to a question that's basically just a gimme the codez I've been weak enough to post it, but would prefer not to get any rep for doing so.

gcc and lccwin32:different result

i try to compile this code:
#include <stdio.h>
void print(FILE *a)
{
int main();
int count=20;
int c;
int stop=0;
char answer;
while(!stop){
while((c=getc(a))!=EOF){
fprintf(stdout,"%c",c);
if(c=='\n'){
count--;
if(!count){
printf("do you want continue:y=for continue/q=for quit");
fflush(stdin);
answer=getchar();
if(answer=='y' || answer=='Y')
count=20;
else if(answer=='Q' || answer=='q'){
printf("you quit this program,press any key and hit the enter to close");
stop=1;
break;
}
else{
printf("argument is unacceptable,rolling back action");
main();
}
}
}
}
if(c==EOF)
stop=1;
}
}
void halt()/*do nothing just for halt and waiting for input*/
{
int a;
scanf("%d",&a);
}
int main()
{
FILE *in,*fopen();
char name1[25];
int a;
printf("enter the name of the file you want to show:");
scanf("%24s",name1);
in=fopen(name1,"r");
if(in==NULL){
printf("the files doesnt exist or it is in another directory, try to enter again\n");
main();
}
else
print(in);
fclose(in);
halt();
return 0;
}
the purpose of the program is to show 20 line content of a file. i compiled it in windows xp with lccwin32 and it works as expected. but problem arise when i change my os to linux (Ubuntu:pricise pangolin 12.04 LTS Desktop) and compile it with gcc.first it seems works fine but until the 20th line and prompt is out, when i put the argument (y for continue , q for quit)and hit the enter, but nothings happen. it just slipped away to elsepart which is starting again the program.so is it the gcc i have buggy or my code doesnt suit with gcc or may be i missed something?
I hate scanf. I would suggest replacing the scanf("%24s",name1) with fgets(s,24,stdin);
(And then unfortunately doing if (s[strlen(s)-1] == '\n') s[strlen(s)-1] = '\0' to get rid of the \n at the end.
I would also suggest:
Not use recursion on main
Use int main(int argc, char *argv[]) and then passing the name of your file as an argument (so you would check that argc > 1 and then use argv[1] as the filename, and then when running the program do ./programname filename)
Still not using scanf
In addition to the issues reported by #Foon you also have those problems :
fflush(stdin) is not working as you think it does.
scanf() leaves the newline character in the input buffer.
Your problem is that there is still a newline (\n) in the input buffer when you call getchar(), so your y/q answer is not even read.
Replacing fflush(stdin) with a solution from 1., or replacing fflush()+getchar() with scanf("\n%c",&answer); should solve that particular issue.

Resources