I am trying to use the RegGetValueA() from the Windows API , but so far I've been unable to get any results from it. At best, I get a "file not found" error, and at worst it crashes hard without any error messages at all.
Below is the current code I have; I'm not sure what is and isn't relevant, and what might be causing the problem or not. I've only got a smidge of C knowledge, so please try to keep it simple.
ffi.cdef([[
typedef void * HKEY;
typedef HKEY * PHKEY;
typedef unsigned long DWORD;
int RegGetValueA(HKEY handle, const char* path, const char* value, int filter_flags, void* unused, char *result, DWORD* size);
]])
local size = ffi.new('DWORD[1]')
size = 1024
local data = ffi.new('char['..size..']')
local dptr = ffi.cast('char*', data)
local lenptr = ffi.cast('DWORD*', size)
test = reg.RegGetValueA(ffi.cast("HKEY", ffi.cast("uintptr_t",0x80000002)), "SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\CereVoice Heather 5.0.1", "CLSID", 0x0000ffff, nil, dptr, lenptr)
When you use ffi.new, what you get is a pointer variable, and you assign the pointer to 1024, and then use ffi.cast to convert to DWORD *, which causes an access address conflict when calling RegGetValueA, so the program crashes.
You only need to modify the code as follows:
local ffi = require("ffi")
ffi.cdef([[
typedef void * HKEY;
typedef HKEY * PHKEY;
typedef unsigned long DWORD;
int RegGetValueA(HKEY handle, const char* path, const char* value, int
filter_flags, void* unused, char *result, DWORD* size);
]])
local size = 1024
local data = ffi.new('char['..size..']')
local dptr = ffi.cast('char*', data)
local lenptr = ffi.new('DWORD[1]', size)
local test = ffi.C.RegGetValueA(ffi.cast("HKEY", ffi.cast("uintptr_t",0x80000002)), "SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\CereVoice Heather 5.0.1", "CLSID", 0x0000ffff, nil, dptr, lenptr)
print(test)
print(ffi.string(dptr))
I get a "file not found" error
This means "registry key not found".
There are two different registries in 64-bit Windows, you should try reading from both of them:
local ffi = require'ffi'
ffi.cdef"int RegGetValueA(uintptr_t, const char*, const char*, uint32_t, void*, char*, uint32_t*);"
local size = 1024
local pcbData = ffi.new'uint32_t[1]'
local pvData = ffi.new('char[?]', size)
local RRF_SUBKEY_WOW6464KEY = 0x00010000
local RRF_SUBKEY_WOW6432KEY = 0x00020000
for _, WOW64_flag in ipairs{RRF_SUBKEY_WOW6464KEY, RRF_SUBKEY_WOW6432KEY} do
pcbData[0] = size
local errcode = ffi.C.RegGetValueA(
0x80000002, -- HKLM
"SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\MS-Anna-1033-20-DSK",
"CLSID",
0x0000ffff + WOW64_flag,
nil,
pvData,
pcbData
)
if errcode == 0 then
break
end
end
print(ffi.string(pvData))
Related
I am using json-c to parse json files in my project. I tried creating json_tokener_parse but this has resulted in seg-fault. could any please check and tell me the reason for segfault.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> // O_RDONLY
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<json-c/json.h>
int main() {
int oflag = O_RDONLY;
const char *path = "file.json";
const int fd = open(path, oflag);
// use stat to find the file size
struct stat stat;
int ret = fstat(fd, &stat);
int mflags = MAP_SHARED; // information about handling the mapped data
int mprot = PROT_READ|PROT_WRITE; // access permissions to the data being mapped
size_t size = stat.st_size;
void *addr = mmap(NULL, size, mprot, mflags, fd, 0);
const char *file = (char *)addr;
json_object * jobj = json_tokener_parse(addr);
//json_parse(jobj);
}
json_tokener_parse() takes a null-terminated string. A text file is not null-terminated. You'll have to use json_tokener_parse_ex() and specify the length.
I am trying to learn more about C++ memory management and type casting. How can I store and retrieve a std::wstring* in a char array? Code or suggestions about what to read would be appreciated.
Here is what I have tried so far. My definition of "Works" is that the correct string appears in the GUI control. "Does not work" means it compiles and runs but gives me a blank in the GUI control.
I'm really curious about why "Wrapper 2" works but not "Wrapper 1".
Integer example (Works):
int* lInt(new int);
*lInt = 1500000;
char lBuffer[sizeof(void*)];
memcpy(lBuffer, lInt, sizeof(void*));
int* lInt2 = (int*)lBuffer;
Memo->Lines->Append(IntToStr(*lInt2)); //C++Builder GUI control
delete lInt;
std::wstring Example (Does not work):
std::wstring* lMyString = new std::wstring();
*lMyString = L"My Name";
char lBuffer[sizeof(void*)];
memcpy(lBuffer, lMyString, sizeof(void*));
std::wstring* lMyString2 = (std::wstring*)lBuffer;
Memo->Lines->Append(lMyString2->c_str()); //C++Builder GUI control
delete lMyString;
Wrapper 1 (Does not work):
struct MyString
{
std::wstring Text;
};
MyString* lMyString = new MyString();
lMyString->Text = L"My Name";
char lBuffer[sizeof(void*)];
memcpy(lBuffer, lMyString, sizeof(void*));
MyString* lMyString2 = (MyString*)lBuffer;
Memo->Lines->Append(lMyString2->Text.c_str()); //C++Builder GUI control
delete lMyString;
Wrapper 2 (Works):
struct MyString
{
MyString(): Text(new std::wstring()){};
~MyString() {delete Text;};
std::wstring* Text;
};
MyString* lMyString = new MyString();
*lMyString->Text = L"My Name";
char lBuffer[sizeof(void*)];
memcpy(lBuffer, lMyString, sizeof(void*));
MyString* lMyString2 = (MyString*)lBuffer;
Memo->Lines->Append(lMyString2->Text->c_str()); //C++Builder GUI control
delete lMyString;
How can I store and retrieve a std::wstring* in a char array?
The better way is to store it in void*:
std::wstring ws;
void *addr = &ws;
// ...
std::wstring retreived = *static_cast<std::wstring*>(addr);
***** std::wstring Example (Does not work) *****
std::wstring* lMyString = new std::wstring();
// ...
char lBuffer[sizeof(void*)];
memcpy(lBuffer, lMyString, sizeof(void*));
std::wstring* lMyString2 = (std::wstring*)lBuffer;
// ...
memcpy used this way actually copies bytes of the stored std::wstring.
void* memcpy( void* dest, const void* src, std::size_t count );
lMyString is a pointer to allocated std::wstring and memcpy copies bytes from memory src points to. What you actually wanted to do is to copy the pointer itself so you need to take address of the pointer:
memcpy(lBuffer, &lMyString, sizeof(void*));
std::wstring* lMyString2 = (std::wstring*)lBuffer;
This is also wrong. You are converting address of the first character in char[], not the actual bytes that you stored in the char array before. You should memcpy it back:
std::wstring* lMyString2 = nullptr;
std::memcpy(&lMyString2, lBuffer, sizeof(void*));
As I said, use void* instead.
In a kernel module, how to list all the kernel symbols with their addresses?
The kernel should not be re-compiled.
I know "cat /proc/kallsyms" in an interface, but how to get them directly from kernel data structures, using functions like kallsyms_lookup_name.
Example
Working module code:
#include <linux/module.h>
#include <linux/kallsyms.h>
static int prsyms_print_symbol(void *data, const char *namebuf,
struct module *module, unsigned long address)
{
pr_info("### %lx\t%s\n", address, namebuf);
return 0;
}
static int __init prsyms_init(void)
{
kallsyms_on_each_symbol(prsyms_print_symbol, NULL);
return 0;
}
static void __exit prsyms_exit(void)
{
}
module_init(prsyms_init);
module_exit(prsyms_exit);
MODULE_AUTHOR("Sam Protsenko");
MODULE_DESCRIPTION("Module for printing all kernel symbols");
MODULE_LICENSE("GPL");
Explanation
kernel/kallsyms.c implements /proc/kallsyms. Some of its functions are available for external usage. They are exported via EXPORT_SYMBOL_GPL() macro. Yes, your module should have GPL license to use it. Those functions are:
kallsyms_lookup_name()
kallsyms_on_each_symbol()
sprint_symbol()
sprint_symbol_no_offset()
To use those functions, include <linux/kallsyms.h> in your module. It should be mentioned that CONFIG_KALLSYMS must be enabled (=y) in your kernel configuration.
To print all the symbols you obviously have to use kallsyms_on_each_symbol() function. The documentation says next about it:
/* Call a function on each kallsyms symbol in the core kernel */
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
unsigned long), void *data);
where fn is your callback function that should be called for each symbol found, and data is a pointer to some private data of yours (will be passed as first parameter to your callback function).
Callback function must have next signature:
int fn(void *data, const char *namebuf, struct module *module,
unsigned long address);
This function will be called for each kernel symbol with next parameters:
data: will contain pointer to your private data you passed as last argument to kallsyms_on_each_symbol()
namebuf: will contain name of current kernel symbol
module: will always be NULL, just ignore that
address: will contain address of current kernel symbol
Return value should always be 0 (on non-zero return value the iteration through symbols will be interrupted).
Supplemental
Answering the questions in your comment.
Also, is there a way to output the size of each function?
Yes, you can use sprint_symbol() function I mentioned above to do that. It will print symbol information in next format:
symbol_name+offset/size [module_name]
Example:
psmouse_poll+0x0/0x30 [psmouse]
Module name part can be omitted if symbol is built-in.
I tried the module and see the result with "dmesg". But a lot of symbols are missing such as "futex_requeue". The output symbol number is about 10K, while it is 100K when I use "nm vmlinux".
This is most likely because your printk buffer size is insufficient to store all the output of module above.
Let's improve above module a bit, so it provides symbols information via miscdevice. Also let's add function size to the output, as requested. The code as follows:
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kallsyms.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/sizes.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#define DEVICE_NAME "prsyms2"
/* 16 MiB is sufficient to store information about approx. 200K symbols */
#define SYMBOLS_BUF_SIZE SZ_16M
struct symbols {
char *buf;
size_t pos;
};
static struct symbols symbols;
/* ---- misc char device definitions ---- */
static ssize_t prsyms2_read(struct file *file, char __user *buf, size_t count,
loff_t *pos)
{
return simple_read_from_buffer(buf, count, pos, symbols.buf,
symbols.pos);
}
static const struct file_operations prsyms2_fops = {
.owner = THIS_MODULE,
.read = prsyms2_read,
};
static struct miscdevice prsyms2_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &prsyms2_fops,
};
/* ---- module init/exit definitions ---- */
static int prsyms2_store_symbol(void *data, const char *namebuf,
struct module *module, unsigned long address)
{
struct symbols *s = data;
int count;
/* Append address of current symbol */
count = sprintf(s->buf + s->pos, "%lx\t", address);
s->pos += count;
/* Append name, offset, size and module name of current symbol */
count = sprint_symbol(s->buf + s->pos, address);
s->pos += count;
s->buf[s->pos++] = '\n';
if (s->pos >= SYMBOLS_BUF_SIZE)
return -ENOMEM;
return 0;
}
static int __init prsyms2_init(void)
{
int ret;
ret = misc_register(&prsyms2_misc);
if (ret)
return ret;
symbols.pos = 0;
symbols.buf = vmalloc(SYMBOLS_BUF_SIZE);
if (symbols.buf == NULL) {
ret = -ENOMEM;
goto err1;
}
dev_info(prsyms2_misc.this_device, "Populating symbols buffer...\n");
ret = kallsyms_on_each_symbol(prsyms2_store_symbol, &symbols);
if (ret != 0) {
ret = -EINVAL;
goto err2;
}
symbols.buf[symbols.pos] = '\0';
dev_info(prsyms2_misc.this_device, "Symbols buffer is ready!\n");
return 0;
err2:
vfree(symbols.buf);
err1:
misc_deregister(&prsyms2_misc);
return ret;
}
static void __exit prsyms2_exit(void)
{
vfree(symbols.buf);
misc_deregister(&prsyms2_misc);
}
module_init(prsyms2_init);
module_exit(prsyms2_exit);
MODULE_AUTHOR("Sam Protsenko");
MODULE_DESCRIPTION("Module for printing all kernel symbols");
MODULE_LICENSE("GPL");
And here is how to use it:
$ sudo insmod prsyms2.ko
$ sudo cat /dev/prsyms2 >symbols.txt
$ wc -l symbols.txt
$ sudo rmmod prsyms2
File symbols.txt will contain all kernel symbols (both built-in and from loaded modules) in next format:
ffffffffc01dc0d0 psmouse_poll+0x0/0x30 [psmouse]
It seems that I can use kallsyms_lookup_name() to find the address of the function, can then use a function pointer to call the function?
Yes, you can. If I recall correctly, it's called reflection. Below is an example how to do so:
typedef int (*custom_print)(const char *fmt, ...);
custom_print my_print;
my_print = (custom_print)kallsyms_lookup_name("printk");
if (my_print == 0) {
pr_err("Unable to find printk\n");
return -EINVAL;
}
my_print(KERN_INFO "### printk found!\n");
I have succeeded in making a modified version of ext2 (so called myext2.ko) and tested it for mount and umount, and something else; the problem occurs when I add the following code into my fs/myext2/file.c and tried to implement a simple "encryption" func, that is, negating the last bit of the read-in string :
ssize_t my_new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
struct iovec iov; //changed
struct kiocb kiocb;
struct iov_iter iter;
ssize_t ret;
//inserted by adward - begin
size_t i;
char buff[len];
for (i=0;i<len;i++){
buff[i] = buf[i] ^ 1;
}
iov.iov_base = (void __user *)buff;
iov.iov_len = len;
printk("Inside my_new_sync_write");
//inserted by adward - end
init_sync_kiocb(&ki_nbytesocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_nbytes = len;
iov_iter_init(&iter, WRITE, &iov, 1, len);
ret = filp->f_op->write_iter(&kiocb, &iter);
if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
return ret;
}
ssize_t my_new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
struct iovec iov = { .iov_base = buf, .iov_len = len };
struct kiocb kiocb;
struct iov_iter iter;
ssize_t ret;
//inserted by adward - begin
size_t i;
//inserted by adward - end
init_sync_kiocb(&kiocb, filp);
kiocb.ki_pos = *ppos;
kiocb.ki_nbytes = len;
iov_iter_init(&iter, READ, &iov, 1, len);
ret = filp->f_op->read_iter(&kiocb, &iter);
if (-EIOCBQUEUED == ret)
ret = wait_on_sync_kiocb(&kiocb);
*ppos = kiocb.ki_pos;
//inserted by adward - begin
for (i=0;i<len;i++){
buf[i] ^= 1;
}
printk("inside my_new_sync_read");
//inserted by adward - end
return ret;
}
The prototype of the above two functions are actually in fs/read_write.c , using by almost all file system types in the kernel code ver 3.17.6; I just copied them into fs/myext2/file.c and make some minor change as commented, so that I can do some test without having to change any Makefile.
But the moment I paste them into my file.c, "sudo make" gives the error message as following:
/home/adward/linux-3.17.6/fs/myext2/file.c:64:15: error: storage size of ‘kiocb’ isn’t known
struct kiocb kiocb;
^
/home/adward/linux-3.17.6/fs/myext2/file.c:65:18: error: storage size of ‘iter’ isn’t known
struct iov_iter iter;
^
and cc1: some warnings being treated as errors
even if I haven't refered to them by changing the func pointers in file_operations in the same source code file, or say, I haven't used them!
P.S.
My file_operation struct now looks like:
const struct file_operations myext2_file_operations = {
.llseek = generic_file_llseek,
.read = new_sync_read, //want to replace with my_new_sync_read
.write = new_sync_write, //want to replace with my_new_sync_write
...
}
Has anyone who have done something similar and crashed into some problems like this one? Please notify me if I have done something remarkable wrong, thanks.
Met the same error before. U should add <linux/aio.h> as ext2 uses asynchronous IO for reading/writing files.
Hope that helps :)
I am trying to set constant values on my GPU's constant memory before launching a kernel which needs these values.
My code (simplified):
__constant__ size_t con_N;
int main()
{
size_t N;
size_t* dev_N = NULL;
cudaError_t cudaStatus;
//[...]
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, &con_N);
if (cudaStatus != cudaSuccess) {
cout<<"cudaGetSymbolAddress (dev_N) failed: "<<cudaGetErrorString(cudaStatus)<<endl;
}
I planned to cudaMemcpy my N to dev_N afterwards.
However, all I get at this point in the code is:
cudaGetSymbolAddress (dev_N) failed: invalid device symbol
I'm working with CUDA 6.5 so it's not a quoted symbol issue, as it is in most of the Q&A I've been checking so far.
I tried to replace con_N with con_N[1] (and remove the & before con_N in cudaGetSymbolAddress parameters): same result.
As the prototype of this function is cudaGetSymbolAddress(void **devPtr , const void* symbol ), I guessed it wanted to be given my symbol's address. However, I tried with cudaStatus = cudaGetSymbolAddress((void **)&dev_N, (const void*) con_N); and I got the same message.
I'm also getting the very same error message when I remove cudaGetSymbolAddress((void **)&dev_N, &con_N) and go directly with cudaMemcpyToSymbol(&con_N, &N, sizeof(size_t)) instead.
I'm afraid I missed something essential. Any help will be greatly appreciated.
The correct usage of cudaGetSymbolAddress is
cudaGetSymbolAddress((void **)&dev_N, con_N)
I'm showing this with the simple example below.
As the documentation explains, the symbol should physically reside on the device. Accordingly, using &con_N in the API call appears to be meaningless, since, being cudaGetSymbolAddress a host API, accessing the address of something residing on the device directly from host should not be possible. I'm not sure if the prototype appearing in the CUDA Runtime API document should better read as `
template<class T>
cudaError_t cudaGetSymbolAddress (void **devPtr, const T symbol)
with device symbol reference instead of device symbol address.
#include <stdio.h>
__constant__ int const_symbol;
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
/***************/
/* TEST KERNEL */
/***************/
__global__ void kernel() {
printf("Address of symbol from device = %p\n", &const_symbol);
}
/********/
/* MAIN */
/********/
int main()
{
const int N = 16;
int *pointer = NULL;
gpuErrchk(cudaGetSymbolAddress((void**)&pointer, const_symbol));
kernel<<<1,1>>>();
printf("Address of symbol from host = %p\n", pointer);
return 0;
}
In my opinion, A line of your code should be fixed like below.
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, con_N);
Hope this helps you.