mmap load shared object and get function pointer
I want to dynamically load a library without using functions from dlfcn.h
i have a folder full of .so files compiled with:
gcc -Wall -shared -fPIC -o filename.so filename.c
And all of them have an entry function named:
void __start(int size, char** cmd);
(I know, probably not the best name)
then i try to call open
over the so, then read the elf header as an Elf64_Ehdr
load it into memory with mmap
(i know i should use mprotect
but i want to make it work first and then add the security) and finally adding the the elf header entry to the pointer returned by mmap (plus an offset of 0x100).
The test code is the following:
#include <elf.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
typedef void (*ptr_t) (int, char**);
void* alloc_ex_memory(int fd) {
struct stat s;
fstat(fd, &s);
void * ptr = mmap(0, s.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
if (ptr == (void *)-1) {
perror("mmap");
return NULL;
}
return ptr;
}
void* load_ex_file(const char* elfFile) {
Elf64_Ehdr header;
void * ptr;
FILE* file = fopen(elfFile, "rb");
if(file) {
fread(&header, 1, sizeof(header), file);
if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
ptr = alloc_ex_memory(fileno(file));
printf("PTR AT -> %pn", ptr);
printf("Entry at -> %lxn", header.e_entry+256);
ptr = (header.e_entry + 256);
} else {
ptr = NULL;
}
fclose(file);
return ptr;
}
return NULL;
}
int main(int argc, char** argv) {
ptr_t func = load_ex_file(argv[1]);
printf("POINTER AT: %pn", func);
getchar();
func(argc, argv);
return 0;
}
Let me explain a bit further:
When i run objdump -d filename.so
i get that the _start
is at 0x6c0
. The elf header entry point returns 0x5c0
(i compensate it adding 256 in dec).
Also pmap
shows an executable area being created at lets say 0x7fdf94d0c000
so the function pointer direction that i get and which i call is at
0x7fdf94d0c6c0
this should be the entry point and callable via function pointer. But what i get is, you guessed it: segfault.
Las thing that i would like to point out is that i have the same example running with (dlopen
, dlsym
, dlclose
) but its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how. (perhaps there is a simpler way that im missing).
I based the code on this jit example
Thank you in advance!
Edit: This is the code of the .c that i compile into .so:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void __start(int size, char** cmd) {
if (size==2) {
if (!strcmp(cmd[1], "-l")) {
printf("******.********.*****@udc.esn");
return;
} else if (!strcmp(cmd[1], "-n")) {
printf("****** ******** *****n");
return;
}
} else if (size==1) {
printf("****** ******** ***** (******.********.*****@udc.es)n");
return;
}
printf("Wrong command syntax: autores [-l | -n]n");
}
c elf mmap
add a comment |
I want to dynamically load a library without using functions from dlfcn.h
i have a folder full of .so files compiled with:
gcc -Wall -shared -fPIC -o filename.so filename.c
And all of them have an entry function named:
void __start(int size, char** cmd);
(I know, probably not the best name)
then i try to call open
over the so, then read the elf header as an Elf64_Ehdr
load it into memory with mmap
(i know i should use mprotect
but i want to make it work first and then add the security) and finally adding the the elf header entry to the pointer returned by mmap (plus an offset of 0x100).
The test code is the following:
#include <elf.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
typedef void (*ptr_t) (int, char**);
void* alloc_ex_memory(int fd) {
struct stat s;
fstat(fd, &s);
void * ptr = mmap(0, s.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
if (ptr == (void *)-1) {
perror("mmap");
return NULL;
}
return ptr;
}
void* load_ex_file(const char* elfFile) {
Elf64_Ehdr header;
void * ptr;
FILE* file = fopen(elfFile, "rb");
if(file) {
fread(&header, 1, sizeof(header), file);
if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
ptr = alloc_ex_memory(fileno(file));
printf("PTR AT -> %pn", ptr);
printf("Entry at -> %lxn", header.e_entry+256);
ptr = (header.e_entry + 256);
} else {
ptr = NULL;
}
fclose(file);
return ptr;
}
return NULL;
}
int main(int argc, char** argv) {
ptr_t func = load_ex_file(argv[1]);
printf("POINTER AT: %pn", func);
getchar();
func(argc, argv);
return 0;
}
Let me explain a bit further:
When i run objdump -d filename.so
i get that the _start
is at 0x6c0
. The elf header entry point returns 0x5c0
(i compensate it adding 256 in dec).
Also pmap
shows an executable area being created at lets say 0x7fdf94d0c000
so the function pointer direction that i get and which i call is at
0x7fdf94d0c6c0
this should be the entry point and callable via function pointer. But what i get is, you guessed it: segfault.
Las thing that i would like to point out is that i have the same example running with (dlopen
, dlsym
, dlclose
) but its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how. (perhaps there is a simpler way that im missing).
I based the code on this jit example
Thank you in advance!
Edit: This is the code of the .c that i compile into .so:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void __start(int size, char** cmd) {
if (size==2) {
if (!strcmp(cmd[1], "-l")) {
printf("******.********.*****@udc.esn");
return;
} else if (!strcmp(cmd[1], "-n")) {
printf("****** ******** *****n");
return;
}
} else if (size==1) {
printf("****** ******** ***** (******.********.*****@udc.es)n");
return;
}
printf("Wrong command syntax: autores [-l | -n]n");
}
c elf mmap
printf("PTR AT -> %lxn", ptr);
is the wrong format for a pointer.%p
is used to print a pointer.
– Andrew Henle
Nov 14 '18 at 10:25
@AndrewHenle edited code.
– Tretorn
Nov 14 '18 at 10:28
add a comment |
I want to dynamically load a library without using functions from dlfcn.h
i have a folder full of .so files compiled with:
gcc -Wall -shared -fPIC -o filename.so filename.c
And all of them have an entry function named:
void __start(int size, char** cmd);
(I know, probably not the best name)
then i try to call open
over the so, then read the elf header as an Elf64_Ehdr
load it into memory with mmap
(i know i should use mprotect
but i want to make it work first and then add the security) and finally adding the the elf header entry to the pointer returned by mmap (plus an offset of 0x100).
The test code is the following:
#include <elf.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
typedef void (*ptr_t) (int, char**);
void* alloc_ex_memory(int fd) {
struct stat s;
fstat(fd, &s);
void * ptr = mmap(0, s.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
if (ptr == (void *)-1) {
perror("mmap");
return NULL;
}
return ptr;
}
void* load_ex_file(const char* elfFile) {
Elf64_Ehdr header;
void * ptr;
FILE* file = fopen(elfFile, "rb");
if(file) {
fread(&header, 1, sizeof(header), file);
if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
ptr = alloc_ex_memory(fileno(file));
printf("PTR AT -> %pn", ptr);
printf("Entry at -> %lxn", header.e_entry+256);
ptr = (header.e_entry + 256);
} else {
ptr = NULL;
}
fclose(file);
return ptr;
}
return NULL;
}
int main(int argc, char** argv) {
ptr_t func = load_ex_file(argv[1]);
printf("POINTER AT: %pn", func);
getchar();
func(argc, argv);
return 0;
}
Let me explain a bit further:
When i run objdump -d filename.so
i get that the _start
is at 0x6c0
. The elf header entry point returns 0x5c0
(i compensate it adding 256 in dec).
Also pmap
shows an executable area being created at lets say 0x7fdf94d0c000
so the function pointer direction that i get and which i call is at
0x7fdf94d0c6c0
this should be the entry point and callable via function pointer. But what i get is, you guessed it: segfault.
Las thing that i would like to point out is that i have the same example running with (dlopen
, dlsym
, dlclose
) but its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how. (perhaps there is a simpler way that im missing).
I based the code on this jit example
Thank you in advance!
Edit: This is the code of the .c that i compile into .so:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void __start(int size, char** cmd) {
if (size==2) {
if (!strcmp(cmd[1], "-l")) {
printf("******.********.*****@udc.esn");
return;
} else if (!strcmp(cmd[1], "-n")) {
printf("****** ******** *****n");
return;
}
} else if (size==1) {
printf("****** ******** ***** (******.********.*****@udc.es)n");
return;
}
printf("Wrong command syntax: autores [-l | -n]n");
}
c elf mmap
I want to dynamically load a library without using functions from dlfcn.h
i have a folder full of .so files compiled with:
gcc -Wall -shared -fPIC -o filename.so filename.c
And all of them have an entry function named:
void __start(int size, char** cmd);
(I know, probably not the best name)
then i try to call open
over the so, then read the elf header as an Elf64_Ehdr
load it into memory with mmap
(i know i should use mprotect
but i want to make it work first and then add the security) and finally adding the the elf header entry to the pointer returned by mmap (plus an offset of 0x100).
The test code is the following:
#include <elf.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
typedef void (*ptr_t) (int, char**);
void* alloc_ex_memory(int fd) {
struct stat s;
fstat(fd, &s);
void * ptr = mmap(0, s.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
if (ptr == (void *)-1) {
perror("mmap");
return NULL;
}
return ptr;
}
void* load_ex_file(const char* elfFile) {
Elf64_Ehdr header;
void * ptr;
FILE* file = fopen(elfFile, "rb");
if(file) {
fread(&header, 1, sizeof(header), file);
if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
ptr = alloc_ex_memory(fileno(file));
printf("PTR AT -> %pn", ptr);
printf("Entry at -> %lxn", header.e_entry+256);
ptr = (header.e_entry + 256);
} else {
ptr = NULL;
}
fclose(file);
return ptr;
}
return NULL;
}
int main(int argc, char** argv) {
ptr_t func = load_ex_file(argv[1]);
printf("POINTER AT: %pn", func);
getchar();
func(argc, argv);
return 0;
}
Let me explain a bit further:
When i run objdump -d filename.so
i get that the _start
is at 0x6c0
. The elf header entry point returns 0x5c0
(i compensate it adding 256 in dec).
Also pmap
shows an executable area being created at lets say 0x7fdf94d0c000
so the function pointer direction that i get and which i call is at
0x7fdf94d0c6c0
this should be the entry point and callable via function pointer. But what i get is, you guessed it: segfault.
Las thing that i would like to point out is that i have the same example running with (dlopen
, dlsym
, dlclose
) but its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how. (perhaps there is a simpler way that im missing).
I based the code on this jit example
Thank you in advance!
Edit: This is the code of the .c that i compile into .so:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void __start(int size, char** cmd) {
if (size==2) {
if (!strcmp(cmd[1], "-l")) {
printf("******.********.*****@udc.esn");
return;
} else if (!strcmp(cmd[1], "-n")) {
printf("****** ******** *****n");
return;
}
} else if (size==1) {
printf("****** ******** ***** (******.********.*****@udc.es)n");
return;
}
printf("Wrong command syntax: autores [-l | -n]n");
}
c elf mmap
c elf mmap
edited Nov 14 '18 at 16:54
Tretorn
asked Nov 14 '18 at 10:06
TretornTretorn
13510
13510
printf("PTR AT -> %lxn", ptr);
is the wrong format for a pointer.%p
is used to print a pointer.
– Andrew Henle
Nov 14 '18 at 10:25
@AndrewHenle edited code.
– Tretorn
Nov 14 '18 at 10:28
add a comment |
printf("PTR AT -> %lxn", ptr);
is the wrong format for a pointer.%p
is used to print a pointer.
– Andrew Henle
Nov 14 '18 at 10:25
@AndrewHenle edited code.
– Tretorn
Nov 14 '18 at 10:28
printf("PTR AT -> %lxn", ptr);
is the wrong format for a pointer. %p
is used to print a pointer.– Andrew Henle
Nov 14 '18 at 10:25
printf("PTR AT -> %lxn", ptr);
is the wrong format for a pointer. %p
is used to print a pointer.– Andrew Henle
Nov 14 '18 at 10:25
@AndrewHenle edited code.
– Tretorn
Nov 14 '18 at 10:28
@AndrewHenle edited code.
– Tretorn
Nov 14 '18 at 10:28
add a comment |
1 Answer
1
active
oldest
votes
its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how.
For this to work, your __start
must be completely stand-alone, and not call any other library (you violated that requirement by calling strcmp
and printf
).
The moment you call an unresolved symbol, you ask the dynamic loader to resolve that symbol, and the loader needs all kinds of info for that. That info is normally set up during dlopen
call. Since you bypassed dlopen
, it is not at all surprising that your program crashes.
Your first step should be to change your code such that __start
doesn't do anything at all (is empty), and verify that you can then call __start
. That would confirm that you are computing its address correctly.
Second, add a crash to that code:
void __start(...)
{
int *p = NULL;
*p = 42; // should crash here
}
and verify that you are observing the crash now. That will confirm that your code is getting called.
Third, remove the crashing code and use only direct system calls (e.g. write(1, "Hellon", 6)
(but don't call write
-- you must implement it directly in your library)) to implement whatever you need.
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
1
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simplydlopen
this library?
– Employed Russian
Nov 21 '18 at 2:52
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53297596%2fmmap-load-shared-object-and-get-function-pointer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how.
For this to work, your __start
must be completely stand-alone, and not call any other library (you violated that requirement by calling strcmp
and printf
).
The moment you call an unresolved symbol, you ask the dynamic loader to resolve that symbol, and the loader needs all kinds of info for that. That info is normally set up during dlopen
call. Since you bypassed dlopen
, it is not at all surprising that your program crashes.
Your first step should be to change your code such that __start
doesn't do anything at all (is empty), and verify that you can then call __start
. That would confirm that you are computing its address correctly.
Second, add a crash to that code:
void __start(...)
{
int *p = NULL;
*p = 42; // should crash here
}
and verify that you are observing the crash now. That will confirm that your code is getting called.
Third, remove the crashing code and use only direct system calls (e.g. write(1, "Hellon", 6)
(but don't call write
-- you must implement it directly in your library)) to implement whatever you need.
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
1
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simplydlopen
this library?
– Employed Russian
Nov 21 '18 at 2:52
add a comment |
its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how.
For this to work, your __start
must be completely stand-alone, and not call any other library (you violated that requirement by calling strcmp
and printf
).
The moment you call an unresolved symbol, you ask the dynamic loader to resolve that symbol, and the loader needs all kinds of info for that. That info is normally set up during dlopen
call. Since you bypassed dlopen
, it is not at all surprising that your program crashes.
Your first step should be to change your code such that __start
doesn't do anything at all (is empty), and verify that you can then call __start
. That would confirm that you are computing its address correctly.
Second, add a crash to that code:
void __start(...)
{
int *p = NULL;
*p = 42; // should crash here
}
and verify that you are observing the crash now. That will confirm that your code is getting called.
Third, remove the crashing code and use only direct system calls (e.g. write(1, "Hellon", 6)
(but don't call write
-- you must implement it directly in your library)) to implement whatever you need.
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
1
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simplydlopen
this library?
– Employed Russian
Nov 21 '18 at 2:52
add a comment |
its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how.
For this to work, your __start
must be completely stand-alone, and not call any other library (you violated that requirement by calling strcmp
and printf
).
The moment you call an unresolved symbol, you ask the dynamic loader to resolve that symbol, and the loader needs all kinds of info for that. That info is normally set up during dlopen
call. Since you bypassed dlopen
, it is not at all surprising that your program crashes.
Your first step should be to change your code such that __start
doesn't do anything at all (is empty), and verify that you can then call __start
. That would confirm that you are computing its address correctly.
Second, add a crash to that code:
void __start(...)
{
int *p = NULL;
*p = 42; // should crash here
}
and verify that you are observing the crash now. That will confirm that your code is getting called.
Third, remove the crashing code and use only direct system calls (e.g. write(1, "Hellon", 6)
(but don't call write
-- you must implement it directly in your library)) to implement whatever you need.
its required that i use the mmap trick. I have seen my professor implement it successfully but i cannot figure out how.
For this to work, your __start
must be completely stand-alone, and not call any other library (you violated that requirement by calling strcmp
and printf
).
The moment you call an unresolved symbol, you ask the dynamic loader to resolve that symbol, and the loader needs all kinds of info for that. That info is normally set up during dlopen
call. Since you bypassed dlopen
, it is not at all surprising that your program crashes.
Your first step should be to change your code such that __start
doesn't do anything at all (is empty), and verify that you can then call __start
. That would confirm that you are computing its address correctly.
Second, add a crash to that code:
void __start(...)
{
int *p = NULL;
*p = 42; // should crash here
}
and verify that you are observing the crash now. That will confirm that your code is getting called.
Third, remove the crashing code and use only direct system calls (e.g. write(1, "Hellon", 6)
(but don't call write
-- you must implement it directly in your library)) to implement whatever you need.
edited Nov 15 '18 at 15:46
answered Nov 15 '18 at 15:16
Employed RussianEmployed Russian
124k20166236
124k20166236
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
1
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simplydlopen
this library?
– Employed Russian
Nov 21 '18 at 2:52
add a comment |
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
1
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simplydlopen
this library?
– Employed Russian
Nov 21 '18 at 2:52
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
Thank you for your answer and sorry about not responding until today: What if i need complex code to be loaded?. Actually the code i uploaded as a sample is the simplest of them all. I cannot implement every syscall by myself. Any ideas?
– Tretorn
Nov 21 '18 at 1:32
1
1
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simply
dlopen
this library?– Employed Russian
Nov 21 '18 at 2:52
@Tretorn "What is I need complex code" -- then you'll need to re-implement part of dynamic loader. But why can't you simply
dlopen
this library?– Employed Russian
Nov 21 '18 at 2:52
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53297596%2fmmap-load-shared-object-and-get-function-pointer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
printf("PTR AT -> %lxn", ptr);
is the wrong format for a pointer.%p
is used to print a pointer.– Andrew Henle
Nov 14 '18 at 10:25
@AndrewHenle edited code.
– Tretorn
Nov 14 '18 at 10:28