I have a list with the following values:
l = [205, 1, 239, 215, 48]
when I convert it with bytes by doing
byte_l = bytes(l)
print(byte_l)
gives:
b'\xcd\x01\xef\xd70'
but I want it to return
b'\xcd\x01\xef\xd7\x30'
when i do
byte_l == b'\xCD\x01\xEF\xD7\x30'
it returns True
What is going on here?
And how do I get it to return what I want it to?
You are seeing the ASCII representation of the bytes the print can interpret. Your last number is 48, whose utf representation is 0. Try this:
x = bytearray(b'\x30')
print(x)
You get:
bytearray(b'0')
If you look at the last character of your print, just after \xd7 (i.e., 215) there is 0, that is the representation of 48 (30 in hexadecimal) in ASCII code.
If you try with this code:
l = [47, 48, 49, 50, 51, 52]
byte_l = bytes(l)
print(byte_l)
this is what you get:
b'/01234'
All bytes were interpreted as ASCII codes.
If you want to print the content of the bytes bypassing the ASCII interpretation, you can use something like this:
print(''.join(['\\x{:02x}'.format(x) for x in byte_l]))
If byte_l = bytes([47, 48, 49, 50, 51, 52]) it gives:
\x2f\x30\x31\x32\x33\x34
while in your case (byte_l = bytes([205, 1, 239, 215, 48])), it prints:
\xcd\x01\xef\xd7\x30
I want to read some data from a file in order to xor this with another sequence.
The content of the file is
00112233445566778899aabbccddeeff
The sequence this should be xored with is
000102030405060708090a0b0c0d0e0f
The result should be:
00102030405060708090a0b0c0d0e0f0
The reason why i get a differnt result is that rust reads the content as ascii, like this:
buffer: [48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55]
buffer: [56, 56, 57, 57, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102]
Is there a way to read the content directly to an hex array or how would one convert this?
You can use hex::decode to convert hex into bytes and then use '^' symbol to do xor operation with bits to get your result.
This does the job, reads 16 byte blocks until the end of the file, converts it to &str and converts it again into a vector of Chars:
let mut buffer = [0;16];
while let Ok(n) = file.read(&mut buffer) {
if n == 0 {
break;
}
let s = match str::from_utf8(&buffer) {
Ok(str) => str,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
let mut content = s.to_string();
let char_vec: Vec<char> = content.chars().collect();
println!("Chars{:?}", char_vec);
}
Consider this totally stupid code:
int main() { __asm__("int $0x2"); }
This causes a segfault when run. 2 is code for NMI in intel's IDT (Section 6.3.1 here).
I am curious on why this segfaults though? What exactly is the control flow which will eventually cause it to segfault?
Also pasting section 6.3.3 of the manual here:
6.3.3 Software-Generated Interrupts
The INT n instruction permits interrupts to be generated from within software by supplying an interrupt vector
number as an operand. For example, the INT 35 instruction forces an implicit call to the interrupt handler for interrupt 35.
Any of the interrupt vectors from 0 to 255 can be used as a parameter in this instruction. If the processor’s
predefined NMI vector is used, however, the response of the processor will not be the same as it would be from an
NMI interrupt generated in the normal manner. If vector number 2 (the NMI vector) is used in this instruction, the
NMI interrupt handler is called, but the processor’s NMI-handling hardware is not activated.
Interrupts generated in software with the INT n instruction cannot be masked by the IF flag in the EFLAGS register.
The gate in the idt contains a descriptor privilege level (DPL) which is the largest caller privilege level (CPL) which is permitted to invoke this entry. A real NMI, which is caused by an electrical signal on the cpu, provides an artificial CPL of 0. In this way, the kernel does not have to differentiate between real signals and fake ones.
System services which are invoked via an int xx will have a numerically larger DPL to permit the instruction to open the gate with an instruction. Depending upon your kernel, it is possible that int 3 (breakpoint), 4 (overflow), and 5 (bounds) will work as direct opcodes to facilitate debugging, the "into" and "bounds" opcodes respectively.
You have found a kernel bug. Your program is trying to perform a CPU operation (int 2) that is forbidden to user-space programs, not an invalid memory access. Therefore, it should have been sent a SIGILL (Illegal instruction) signal, not a SIGSEGV signal.
The reason for the bug is probably that this particular forbidden operation is reported to the operating system with a "#GP fault" instead of a "#UD fault" (in the terms used by the x86 architecture manual). #GP faults are also used to report invalid memory accesses, and whoever wrote the code to map that to a signal didn't bother making a distinction between "actual invalid memory access" and "improper use of int reported with #GP". I observe this bug as well, on both Linux and NetBSD, so it must be an easy mistake to make.
When you're debugging a problem involving signals, it is often helpful to establish a signal handler for the troublesome signal, using sigaction with SA_SIGINFO in the flags. When you set SA_SIGINFO, the handler receives two additional arguments that provide detailed information about the signal. You don't have to use those arguments in the signal handler; instead what you do is run the program under a debugger, allow the signal to be delivered, and then inspect the details in the debugger. Here's a modification to your program that does that:
#include <signal.h>
#include <unistd.h>
#include <ucontext.h>
void handler(int s, siginfo_t *si, void *uc)
{
pause();
}
int main(void)
{
struct sigaction sa;
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGBUS, &sa, 0);
sigaction(SIGFPE, &sa, 0);
sigaction(SIGILL, &sa, 0);
sigaction(SIGSEGV, &sa, 0);
sigaction(SIGSYS, &sa, 0);
sigaction(SIGTRAP, &sa, 0);
asm("int $0x2");
}
(The uc argument is a pointer to a ucontext_t, but that type is declared in <ucontext.h>, not <signal.h>, so the spec says you must define the handler to take a third argument of type void * and then cast it if you want to use it.)
I set up the handler for all of the signals corresponding to fatal, synchronous CPU exceptions, because why not. The pause is just to make execution stop indefinitely inside the handler, so I can hit control-C to break into the debugger and the signal frame will be available.
Here's what I get on Linux:
(gdb) bt
#0 0x00007ffff7eb4af4 in __libc_pause ()
at ../sysdeps/unix/sysv/linux/pause.c:29
#1 0x000055555555516d in handler (s=11, si=0x7fffffffd830, uc=0x7fffffffd700)
at test.c:5
#2 <signal handler called>
#3 main () at test.c:14
(gdb) frame 1
#1 0x000055555555516d in handler (s=11, si=0x7fffffffd830, uc=0x7fffffffd700)
at test.c:5
5 pause();
(gdb) p *si
$1 = {si_signo = 11, si_errno = 0, si_code = 128, __pad0 = 0, _sifields = {
_pad = {0 <repeats 28 times>}, _kill = {si_pid = 0, si_uid = 0}, _timer = {
si_tid = 0, si_overrun = 0, si_sigval = {sival_int = 0,
sival_ptr = 0x0}}, _rt = {si_pid = 0, si_uid = 0, si_sigval = {
sival_int = 0, sival_ptr = 0x0}}, _sigchld = {si_pid = 0, si_uid = 0,
si_status = 0, si_utime = 0, si_stime = 0}, _sigfault = {si_addr = 0x0,
si_addr_lsb = 0, _bounds = {_addr_bnd = {_lower = 0x0, _upper = 0x0},
_pkey = 0}}, _sigpoll = {si_band = 0, si_fd = 0}, _sigsys = {
_call_addr = 0x0, _syscall = 0, _arch = 0}}}
(gdb) p *(ucontext_t *)uc
$2 = {uc_flags = 7, uc_link = 0x0, uc_stack = {ss_sp = 0x0, ss_flags = 0,
ss_size = 0}, uc_mcontext = {gregs = {0, 0, 8, 582, 93824992235632,
140737488346656, 0, 0, 11, 140737488345936, 140737488346432, 0, 0, 0,
140737352200658, 140737488346272, 93824992235964, 66050,
12103423998558259, 18, 13, 0, 0}, fpregs = 0x7fffffffd8c0,
__reserved1 = {0, 1, 140737354129808, 140737488345320, 140737353799024,
140737354129808, 8455580781, 140737354130672}}, uc_sigmask = {__val = {
0, 11, 128, 0 <repeats 13 times>}}, __fpregs_mem = {cwd = 0, swd = 0,
ftw = 0, fop = 0, rip = 140737488346656, rdp = 0, mxcsr = 895,
mxcr_mask = 0, _st = {{significand = {0, 0, 0, 0}, exponent = 0,
__glibc_reserved1 = {0, 0, 0}}, {significand = {8064, 0, 65535, 0},
exponent = 0, __glibc_reserved1 = {0, 0, 0}}, {significand = {0, 0, 0,
0}, exponent = 0, __glibc_reserved1 = {0, 0, 0}}, {significand = {0,
0, 0, 0}, exponent = 0, __glibc_reserved1 = {0, 0, 0}}, {
significand = {0, 0, 0, 0}, exponent = 0, __glibc_reserved1 = {0, 0,
0}}, {significand = {0, 0, 0, 0}, exponent = 0, __glibc_reserved1 = {
0, 0, 0}}, {significand = {0, 0, 0, 0}, exponent = 0,
__glibc_reserved1 = {0, 0, 0}}, {significand = {0, 0, 0, 0},
exponent = 0, __glibc_reserved1 = {0, 0, 0}}}, _xmm = {{element = {0,
0, 0, 0}} <repeats 16 times>}, __glibc_reserved1 = {
0 <repeats 18 times>, 1179670611, 836, 7, 0, 832, 0}}, __ssp = {0, 0, 0,
3}}
The siginfo_t structure is basically useless; it has si_code == 128, which means "this signal was generated by the kernel but we're not going to tell you anything else about it," and all the other fields are zero. I consider this to be another kernel bug.
The ucontext_t structure is more useful; in particular
(gdb) p/x ((ucontext_t *)uc)->uc_mcontext.gregs[REG_RIP]
$3 = 0x5555555551bc
This is the address of the instruction that caused the signal. If I disassemble main...
(gdb) disas main
...
0x00005555555551b7: callq 0x555555555030 <sigaction#plt>
0x00005555555551bc: int $0x2
0x00005555555551be: mov $0x0,%eax
0x00005555555551c3: leaveq
0x00005555555551c4: retq
... I see that the instruction that caused the signal is indeed the int $0x2.
On NetBSD I get something slightly different:
(gdb) p *si
$1 = { si_pad = "[garbage]", _info = {
_signo = 11, _code = 2, _errno = 0, _pad = 0, _reason = {
_rt = {_pid = -146410395, _uid = 32639, _value = {sival_int = 4,
sival_ptr = 0x4}}, _child = {_pid = -146410395, _uid = 32639,
_status = 4, _utime = 0, _stime = 0}, _fault = {
_addr = 0x7f7ff745f465 <__sigemptyset14>, _trap = 4, _trap2 = 0,
_trap3 = 0}, _poll = {_band = 140187586131045, _fd = 4}}}}
This siginfo_t has actually been filled out. si_code 2 for a SIGSEGV is SEGV_ACCERR ("Invalid permissions for mapped object") which is not nonsense. There is not enough information in the headers or the manpages for me to understand what _trap = 4 means, or why _addr is pointing to an address somewhere inside the C library, and I don't feel like source-diving the NetBSD kernel today. ;-)
Also for reasons I don't feel like investigating today, gdb on NetBSD doesn't have access to the definition of ucontext_t (even though I explicitly included ucontext.h) so I had to dump it out raw:
(gdb) p *(ucontext_t *)uc
No symbol "ucontext_t" in current context.
(gdb) x/40xg uc
0x7f7fffffd7b0: 0x00000000000a000d 0x0000000000000000
0x7f7fffffd7c0: 0x0000000000000000 0x0000000000000000
0x7f7fffffd7d0: 0x0000000000000000 0x0000000000000000
0x7f7fffffd7e0: 0x0000000000000000 0x0000000000000005
0x7f7fffffd7f0: 0x00007f7fffffdb50 0x0000000000000000
0x7f7fffffd800: 0x00007f7ff7483a0a 0x0000000000000002
0x7f7fffffd810: 0x000000000000000d 0x00007f7ff749f340
0x7f7fffffd820: 0x0000000000000246 0x00007f7fffffdb90
0x7f7fffffd830: 0x00007f7ffffffdea 0x00007f7ff511a4c0
0x7f7fffffd840: 0x00007f7ffffffdea 0x00007f7fffffdb70
0x7f7fffffd850: 0x00007f7fffffffe0 0x0000000000000000
0x7f7fffffd860: 0x0000000000000000 0x0000000000000000
0x7f7fffffd870: 0x000000000000003f 0x00007f7ff748003f
0x7f7fffffd880: 0x0000000000000004 0x0000000000000012
0x7f7fffffd890: 0x0000000000400af5 0x000000000000e033 <---
0x7f7fffffd8a0: 0x0000000000010246 0x00007f7fffffdb50
0x7f7fffffd8b0: 0x000000000000e02b 0x00007f7ff7ffd0c0
0x7f7fffffd8c0: 0x000000000000037f 0x0000000000000000
0x7f7fffffd8d0: 0x0000000000000000 0x0000ffbf00001f80
0x7f7fffffd8e0: 0x0000000000000000 0x0000000000000000
(gdb) disas main
Dump of assembler code for function main:
...
0x0000000000400af0 <+166>: callq 0x400810 <__sigaction14#plt>
0x0000000000400af5 <+171>: int $0x2
0x0000000000400af7 <+173>: leaveq
0x0000000000400af8 <+174>: retq
The only address within the memory region pointed to by uc that bears any correspondence with the text of the program is 0x0000000000400af5, which is, again, the address of the int instruction.
I am loading multiple char values in armv7 program using vldm instruction,
but all four values is loading one s register, but I need to expand this values in floating point register (q0).
Please help me. This is my C code:
void sum(){
int sum =0;
char *p =NULL;
p=( char *) malloc(sizeof( char ) *10);
for( int i=0; i<16;++i){
p[i]=i; sum +=i;
}
printf("sum =%d\n",sum);
}
Here is a typical text book example for loading/storing multiple values from/to the vector banks to general purpose registers that may hold destination and source addresses.
VLDM r1!, {d0-d7}
VSTM r0!, {d0-d7}
If you are using gdb you may get a better visual of a particular set of banks or groups of registers.
(gdb) p $q0
{u8 = {0 <repeats 16 times>}, u16 = {0, 0, 0, 0, 0, 0, 0, 0}, u32 = {0, 0, 0, 0}, u64 = {0, 0}, f32 = {0, 0, 0, 0}, f64 = {0, 0}}
I would like to create an SSE register with values that I can store in an array of integers, from another SSE register which contains flags 0xFFFF and zeros. For example:
__m128i regComp = _mm_cmpgt_epi16(regA, regB);
For the sake of argument, lets assume that regComp was loaded with { 0, 0xFFFF, 0, 0xFFFF }. I would like to convert this into say { 0, 80, 0, 80 }.
What I had in mind was to create an array of integers, initialized to 80 and load them to a register regC. Then, do a _mm_and_si128 bewteen regC and regComp and store the result in regD. However, this does not do the trick, which led me to think that I do not understand the positive flags in SSE registers. Could someone answer the question with a brief explanation why my solution does not work?
short valA[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
short valB[16] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10 };
short ones[16] = { 1 };
short final[16];
__m128i vA, vB, vOnes, vRes, vRes2;
vOnes = _mm_load_si128((__m128i *)&(ones)[0] );
for( i=0 ; i < 16 ;i+=8){
vA = _mm_load_si128((__m128i *)&(valA)[i] );
vB = _mm_load_si128((__m128i *)&(valB)[i] );
vRes = _mm_cmpgt_epi16(vA,vB);
vRes2 = _mm_and_si128(vRes,vOnes);
_mm_storeu_si128((__m128i *)&(final)[i], vRes2);
}
You only set the first element of array ones to 1 (the rest of the array is initialised to 0).
I suggest you get rid of the array ones altogether and then change this line:
vOnes = _mm_load_si128((__m128i *)&(ones)[0] );
to:
vOnes = _mm_set1_epi16(1);
Probably a better solution though, if you just want to convert SIMD TRUE (0xffff) results to 1, would be to use a shift:
for (i = 0; i < 16; i += 8) {
vA = _mm_loadu_si128((__m128i *)&pA[i]);
vB = _mm_loadu_si128((__m128i *)&pB[i]);
vRes = _mm_cmpgt_epi16(vA, vB); // generate 0xffff/0x0000 results
vRes = _mm_srli_epi16(vRes, 15); // convert to 1/0 results
_mm_storeu_si128((__m128i *)&final[i], vRes2);
}
Try this for loading 1:
vOnes = _mm_set1_epi16(1);
This is shorter than creating a constant array.
Be careful, providing less array values than array size in C++ initializes the other values to zero. This was your error, and not the SSE part.
Don't forget the debugger, modern ones display SSE variables properly.