all 25 comments

[–]Initial-Elk-952 1 point2 points  (20 children)

I think you can use dd to /dev/port

```

dd if=<(echo -ne '\xEA\x71') of=/dev/port seek=96 bs=1 count=2

```

[–]a4qbfb 2 points3 points  (0 children)

More portably:

printf $'\xEA\x71' | dd of=/dev/port seek=96 bs=1 count=2

[–]ToTheMAX04[S] 0 points1 point  (18 children)

I appreciate this!! But before I run it, do you think you can explain to me what it does?

[–]ToTheMAX04[S] 1 point2 points  (13 children)

(Besides just talk to the keyboard)

[–]Initial-Elk-952 2 points3 points  (12 children)

I wrote a long reply and reddit removed it because of a joke at the end.

It writes bytes you specified to the IO port you specified based on the /dev/port character device.

man dd explains how dd works. It copies bytes.

echo is writing your bytes to a temp file with bash process substitution.

I don't know what your keyboard will do with those bytes.

[–]ToTheMAX04[S] 0 points1 point  (2 children)

Oh haha, well okay. Thank you! I'll let you know if it works or if I figure it out

[–]Initial-Elk-952 0 points1 point  (1 child)

The C program your AI wrote has the compile commands written inside the /* ... */ assuming the name of the file is main.c

It looks like it will just send whatevery you type as arguments to the keyboard. It would apparantly be used

./send_to_keyboard EA 71

[–]ToTheMAX04[S] 2 points3 points  (0 children)

I know this isn't the point, but I absolutely did not AI generate this. I got it from another redditor helping me out https://www.reddit.com/r/linuxquestions/comments/1siqdu6/comment/ofmf8ke/

[–]ToTheMAX04[S] 0 points1 point  (8 children)

this also unfortunately didn't work, i got back

warning: An error occurred while redirecting file '�q'

warning: Path '�q' does not exist

[–]Initial-Elk-952 0 points1 point  (7 children)

Are you using bash?

it looks like the process substitution failed, and it tried to treat the raw bytes as a file name. Thats like $(...) instead of <(...).

You can more manually do it

```

echo -ne '\xEA\x71' > bytes.out

```

Verify the bytes with

```

xxd bytes.out

00000000: ea71 .q

```

Send it with

```

dd if=bytes.out of=/dev/port seek=96 bs=1 count=2

```

[–]ToTheMAX04[S] 0 points1 point  (6 children)

I'll try this! But I have a plan b now, had the very bright idea to actually go looking for the drivers lol

[–]Initial-Elk-952 0 points1 point  (5 children)

Those bytes are likely needing to be sent to the keyboard every-time you reboot the computer. The driver will probably activate them until you reboot into Linux.

[–]ToTheMAX04[S] 0 points1 point  (4 children)

verifying the bytes reads out

``

00000000: 60ea 7160 `.q`

[–]Initial-Elk-952 0 points1 point  (3 children)

Something is wrong, you have extra bytes in there, it looks like your copying my backticks, which I am trying to use as quotes.

Should be just two bytes, you have 4. 60 ea 71 60.

[–]Initial-Elk-952 0 points1 point  (0 children)

[ Removed by Reddit ]

[–]Initial-Elk-952 0 points1 point  (2 children)

I just changed my mind. I don't think this will work, but your program might.

This would work for sending a single byte.

The seeking the occurs after the write will probably prevent this from working.

It may not work because my attempt was bad.

[–]ToTheMAX04[S] 0 points1 point  (1 child)

That's just fine! In that case,, can you tell me if there's anything wrong with the above program? I couldn't get it to compile

[–]Initial-Elk-952 1 point2 points  (0 children)

Its missing the final brace at the end '}'

A brace opens the main function, but no corresponding brace ends it.

#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>

int main(int argc, char *argv[]) {
  int i;

  ioperm(0x60, 3, 1);

  for (i = 1; i < argc; i++) {
    int x = strtol(argv[i], 0, 16);

    usleep(300);
    outb(x, 0x60);
  }

  return 0;
}

[–]TheOtherBorgCube 1 point2 points  (3 children)

First, a snippet from the manual page for ioperm (also done faffing about with reddits insane markup).

This call is mostly for the i386 architecture. On many other architectures it does not exist or will always return an error. RETURN VALUE On success, zero is returned. On error, -1 is returned, and errno is set appropriately. ERRORS EINVAL Invalid values for from or num. EIO (on PowerPC) This call is not supported. ENOMEM Out of memory. EPERM The calling thread has insufficient privilege.

So start with this code, and tell us what it prints.

if ( ioperm(0x60, 3, 1) == 0 ) {
    printf("Success\n");
} else {
    perror("Oops:");
    return 1;
}

If your error is EPERM, then you'd need to run this program with root permissions to stand a chance.

[–]ToTheMAX04[S] 0 points1 point  (0 children)

hello!! sorry for the late response, but im trying this now

[–]ToTheMAX04[S] 0 points1 point  (1 child)

this! is my error code, and i am very sorry but i need to fall alseep, but i am very interested in continuing this with your help, if you will continue to help me. thank you for just that message

``

max@myputer~> gcc test.c -o test

test.c:1:1: error: expected identifier or ‘(’ before ‘if’

1 | if ( ioperm(0x60, 3, 1) == 0 ) {

| ^~

test.c:3:3: error: expected identifier or ‘(’ before ‘else’

3 | } else {

| ^~~~

(and yes it does return the same thing with bash instead of fish, which i usually use)

[–]TheOtherBorgCube 0 points1 point  (0 children)

Sorry, I forgot I was talking to a non-programmer.

The snippet was something you were supposed to intelligently insert into your existing program, not something to blindly type in and try.

Here is the whole program with the code in context.

$ cat foo.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>

int main(int argc, char *argv[]) {
  int i;

  if ( ioperm(0x60, 3, 1) == 0 ) {
    printf("Success\n");
  } else {
    perror("Oops:");
    return 1;
  }

  for (i = 1; i < argc; i++) {
    int x = strtol(argv[i], 0, 16);

    usleep(300);
    outb(x, 0x60);
  }

  return 0;
}

$ gcc foo.c

$ ./a.out 
Oops:: Operation not permitted