I am writing a program that passes text to a library function.
This function expects the text parameter to be of type unsigned char*.
So how can I properly pass a String to that function? I fail at converting an existing char* to unsigned char* and writing a new value into an unsigned char* variable via strncpy also didn't work.
Edit:
Here is a small example:
That is the function I need to call:
int count (void *index, uchar *pattern, uint length, uint *numocc);
This is what I have in my code:
count(index,?argv[2]?, length, numocc);
You can do typecasting with (unsigned char*). I am posting a small example may be it help you(read comments):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(unsigned char* str){ // argument should be unsigned char*
printf("\n In side fun: %s\n", str);
}
int main(){
char* s = "your_name"; // s is char*
func((unsigned char*)s); // notice type casting
return 1;
}
and it works:
~$ gcc x.c -Wall
~$ ./a.out
In side fun: your_name
~$
EDIT:
count(index, (uchar*)argv[2], length, numocc);
^ typecast (uchar*)
uchar* may be a typedef ed in your code like:
typedef unsigned char* uchar*
Related
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
char *preorden="GEAIBMCLDFKJH";//line 5
error in the above line
char *inorden="IABEGLDCFMKHJ";//line 6
error in this line
char *postorden;
error in this line
void post(char *pre, char *in, char *pos,int n)
{
int longIzqda;
if(n!=0){
pos[n-1]=pre[0];
longIzqda=strchr(in,pre[0])-in;
post (pre+1,in,pos,longIzqda);
post (pre+1+longIzqda,in+1+longIzqda,pos+longIzqda,n-1-longIzqda);
}
}
int main(int argc,char *argv[])
{
int aux;
aux=strlen(preorden);//convert to string
postorden=(char *)malloc(aux*sizeof(char));//use of malloc function
if (postorden){
printf("The preorden is: %s\n",preorden);
printf("The inorden is: %s\n",inorden);
post(preorden,inorden,postorden,aux);
postorden[aux]='\0';
printf("The postorden calculated is: %s\n",postorden);
free(postorden);
}
else{
fprintf(stderr,"Whithout memory\n");
return 1; // return 1
}
return 0;
}
the error is in the line 5 and 6
the compiler says:
deprecated conversion from string constant to 'char*' [-Wwrite-strings]
There are few issues with your code, firstly this
char *preorden="GEAIBMCLDFKJH";//line 5
forces compiler to warn you like below if compiled with -Wwrite-strings flags in C
deprecated conversion from string constant to 'char*'
[-Wwrite-strings]
because the string literal GEAIBMCLDFKJH stored in read only section of primary memory i.e pointer where it points, that contents is read only, hence instead of char* use const char*. for e.g
char *preorden = "GEAIBMCLDFKJH";/* preorden is normal pointer but "GEAIBMCLDFKJH" is read only, hence error */
And
const char *preorden = "GEAIBMCLDFKJH"; /* const char *ptr means ptr contents is read only */
Secondly, here
postorden=(char *)malloc(aux*sizeof(char));//use of malloc function
casting of malloc result is not required as malloc() return type is void* which is automatically and safely promoted to any other pointer type, Read Do I cast the result of malloc?. for e.g
postorden = malloc(aux * sizeof(*postorden));//use of malloc function
Also here(this point is about wrong comment on below line, please don't mind)
aux=strlen(preorden);//convert to string
strlen(preorden) returns the length of string pointed by preorden and gets assigned to aux not as written in comments(convert to string).
And change the post() definition to
void post(const char *pre, const char *in, char *pos,int n) {
/* some code*/
}
The message “deprecated conversion from string constant to 'char*' [-Wwrite-strings]” arises because the code was compiled as C++ code, which has different rules about string literals and pointer conversions from C.
This can be fixed by compiling the code as C code or worked around by inserting an explicit cast to char *.
In Demystifying the Execve Shellcode is explained a way to write an execve shellcode:
#include<stdio.h>
#include<string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
What does the line int (*ret)() = (int(*)())code; do?
int (*ret)() = (int(*)())code;
~~~~~~~~~~~~ ~~~~~~~~~~~~~~
1 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
It defines ret as a pointer to a function which has no parameter () and returns int. So, Those () indicates the definition of parameters of a function.
It's for casting code to a pointer to a function which has no parameter () and returns int.
Casts code as a function and assigns it to ret. After that you can call ret();.
unsigned char code[] = "\x31\xc0\x50\x68\x6e\x2f\...
It is a sequence of machine instructions represented by hex values. It will be injected to the code as a function.
(*(void(*)())shellcode)()
==
p = (void(*)()) shellcode;
(*p)();
Can this function pointer part be re-written in a simpler form?
I don't know if you think this is simpler, but maybe:
#include <stdio.h>
#include <string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
typedef int(*shellcode_t)();
int main(int argc, char ** argv) {
printf("Shellcode Length: %ld\n", strlen(code));
shellcode_t ret = (shellcode_t)code;
ret();
}
The int line declares the ret() function, by pointing to the code[] array; in other words, the function is mapped to the code[] binary instructions.
The \x construct is a safe way to embed hexadecimal characters in a string. You could for instance replace “\x31” by “1” as the character code of “1” is 49, or hexadecimal 31.
In Demystifying the Execve Shellcode is explained a way to write an execve shellcode:
#include<stdio.h>
#include<string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
What does the line int (*ret)() = (int(*)())code; do?
int (*ret)() = (int(*)())code;
~~~~~~~~~~~~ ~~~~~~~~~~~~~~
1 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
It defines ret as a pointer to a function which has no parameter () and returns int. So, Those () indicates the definition of parameters of a function.
It's for casting code to a pointer to a function which has no parameter () and returns int.
Casts code as a function and assigns it to ret. After that you can call ret();.
unsigned char code[] = "\x31\xc0\x50\x68\x6e\x2f\...
It is a sequence of machine instructions represented by hex values. It will be injected to the code as a function.
(*(void(*)())shellcode)()
==
p = (void(*)()) shellcode;
(*p)();
Can this function pointer part be re-written in a simpler form?
I don't know if you think this is simpler, but maybe:
#include <stdio.h>
#include <string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
typedef int(*shellcode_t)();
int main(int argc, char ** argv) {
printf("Shellcode Length: %ld\n", strlen(code));
shellcode_t ret = (shellcode_t)code;
ret();
}
The int line declares the ret() function, by pointing to the code[] array; in other words, the function is mapped to the code[] binary instructions.
The \x construct is a safe way to embed hexadecimal characters in a string. You could for instance replace “\x31” by “1” as the character code of “1” is 49, or hexadecimal 31.
I have been working on getting the sha1() function working from openssl/sha.h however I am getting random output and some warning. I have read quite a bit and tried some of the example codes but I get warning on all of it and it doesn't display correctly.
Here is code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/sha.h>
int main()
{
const unsigned char data[] = "Hello, World";
unsigned long length = sizeof(data);
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
printf("%02x \n", hash);
return 0;
}
Below is the warning I am getting:
sha.c: In function ‘main’:
sha.c:12: warning: ‘SHA1’ is deprecated (declared at /usr/include/openssl/sha.h:124)
sha.c:13: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 2 has type ‘unsigned char *’
sha.c:13: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 2 has type ‘unsigned char *’
When I run it and I get the output:
62652b34
Any help would be great!
It also took me a while before I figured it all out. The best way is to use EVP, it provides generic functions for almost everything.
#include <openssl/evp.h>
You need to call this im main before calling you hash function. To initialize your hashes. Otherwise openssl will complain that the algorithm is not available.
OpenSSL_add_all_algorithms();
mode must be "SHA256", "SHA512", "SHA1" as string.
dataToHash is the input, dataSize is the size of the input,
outHashed should already be allocated, the hash will be written there
unsigned int hash(const char *mode, const char* dataToHash, size_t dataSize, unsigned char* outHashed) {
unsigned int md_len = -1;
const EVP_MD *md = EVP_get_digestbyname(mode);
if(NULL != md) {
EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, dataToHash, dataSize);
EVP_DigestFinal_ex(&mdctx, outHashed, &md_len);
EVP_MD_CTX_cleanup(&mdctx);
}
return md_len;
}
A use example (this is not tested, I use the above code in a c++ wrapper)
const char *inData = "test data2";
unsigned char outHash[20]; // output is already allocated
hash("SHA1", inData, 10, outHash);
You shouldn't use the SHA1 method directly it is deprecated (your code could blow up with the next version).
If you want to use your version you need to print each char as hex:
int i;
for(i=0; i<SHA_DIGEST_LENGTH; i++) {
printf("%02x", hash[i]);
}
You can't dump the entire buffer that way. you need to loop it, such as below. The value you're getting for your output is actually the address of the hash buffer, which is clearly not what you're looking for. You want the hex-bytes in the buffer dumped as text
So...
int main()
{
const unsigned char data[] = "Hello, World";
unsigned long length = sizeof(data);
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
int i=0;
for (;i< sizeof(hash)/sizeof(hash[0]);++i)
printf("%02x \n", hash[i]);
return 0;
}
Regarding your warnings, the deprecation is because this interface is out-dated for performing the crypto-op you're attempting (SHA1). There are newer interfaces in OpenSSL that are current. Consider the EVP interface specifically.
printf("%02u \n", hash);
Remove warnings by printing unsigned char
char *test = "hello";
test = change_test("world");
printf("%s",test);
char* change_test(char *n){
printf("change: %s",n);
return n;
}
im trying to pass a 'string' back to a char pointer using a function but get the following error:
assignment makes pointer from integer without a cast
what am i doing wrong?
A function used without forward declaration will be considered having signature int (...). You should either forward-declare it:
char* change_test(char*);
...
char* test = "hello";
// etc.
or just move the definition change_test before where you call it.
printf() prints the text to the console but does not change n. Use this code instead:
char *change_test(char *n) {
char *result = new char[256];
sprintf(result, "change: %s", n);
return result;
}
// Do not forget to call delete[] on the value returned from change_test
Also add the declaration of change_test() before calling it:
char *change_test(char *n);
You're converting an integer to a pointer somewhere. Your code is incomplete, but at a guess I'd say it's that you're not defining change_test() before you use it, so the C compiler guesses at its type (and assumes it returns an integer.) Declare change_test() before calling it, like so:
char *change_test(char *n);
thanks a bunch guys! didnt think i would have this problem solved by lunch. here is the final test class
/* standard libraries */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* change_test(char*);
int main(){
char *test = "hello";
test = change_test("world");
printf("%s",test);
return (EXIT_SUCCESS);
}
char* change_test(char *n){
return n;
}