I want to know my computer architecture, so i typoe command on my os to check it .It shows that my computer architecture is 'i686' when i type uname -mand arch.But it show i686 i686 i386 GNU/Linuxwhen i type uname -a.I have known that uname -a prints print all information and uname -m print the machine hardware name. So why it prints i386 when i type uname -a.And what's the difference between them .
From man uname:
-a, --all
print all information [...]
-m, --machine
print the machine hardware name
-p, --processor
print the processor type or "unknown"
-i, --hardware-platform
print the hardware platform or "unknown"
So, the triple from the output of uname -a correspond to machine processor hardware, in that order.
Related
It has been mentioned that when employing x86_64 Docker images on an M1 Mac, when no ARM64 image is available, that container will start under qemu emulation for compatibility. (At the cost of performance.)
Often times when I'm running a collection of containers (and integration tests against the lot), I'll see qemu-system-aarch64 pegging a few cores.
My question: How can I determine, for a given list of running containers (ie. docker ps), which ones are running natively and which are being emulated?
This is true also for Docker running on amd64 CPU, when the image is build for arm64, and the whole mechanism is explained in this SO
The mechanism for emulation is using the information in the elf to recognize the architecture for which the process is build, and if the architecture of the binary differs from the architecture of the CPU, it starts the qemu emulation. Though the recognizing of the architecture is more related to the process, there is still information about the targeted architecture of the docker image. The targeted architecture is determined from the "Architecture" flag on the image which was set when the image was build. Any of the containers that will run the image will be associated (trough the image) with this flag.
It should be noted that the "Architecture" flag on the image will not prevent a single process inside the image, which is compiled for a different architecture than the flagged one to run. The reason for this is that bitfmt (which is the underlying mechanism sitting inside the linux kernel) will always try to recognize the architecture from the magic numbers of the elf and will start the the emulation if the magic number is recognized.
To list the architecture of the containers, you can use the following "quick" query:
for i in `docker ps --format "{{.Image}}"` ; do docker image inspect $i --format "$i -> {{.Architecture}} : {{.Os}}" ;done
The command will print the container name, the architecture and the os of the image.
To avoid typing this command multiple times, you can add alias in .bashrc as follows:
alias docker-arch-ps='for i in `docker ps --format "{{.Image}}"` ; do docker image inspect $i --format "$i -> {{.Architecture}} : {{.Os}}" ;done';
After this, you can use simple docker-arch-ps to get the list of the containers and their architecture.
As an improvement of the #jordanvrtanoski's answer, I've done two additional commands
docker-ps-arch:
#!/bin/bash
OPT=$#
set -euo pipefail
docker container ls $OPT --format "{{.ID}}\t{{.Image}}\t{{.Command}}\t{{.Status}}\t{{.Names}}" |
awk -F '\t' 'BEGIN {OFS=FS} { "docker image inspect --format \"{{.Os}}/{{.Architecture}}\" "$2" #"NR | getline $6; print }' |
column --table --table-columns "CONTAINER ID,IMAGE,COMMAND,STATUS,NAME,ARCH" -o ' ' -s $'\t'
and
docker-images-arch:
#!/bin/bash
OPT=$#
set -euo pipefail
docker image ls $OPT --format "{{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}" |
awk -F '\t' 'BEGIN {OFS=FS} { "docker image inspect --format \"{{.Os}}/{{.Architecture}}\" "$3" #"NR | getline $5; print }' |
column --table --table-columns "REPOSITORY,TAG,IMAGE ID,SIZE,ARCH" -o ' ' -s $'\t'
They produce outputs close to the original commands and support options of docker container ls and docker image ls.
$ docker-ps-arch -a
CONTAINER ID IMAGE COMMAND STATUS NAME ARCH
261767e38db2 hello-world "/hello" Exited (0) About an hour ago practical_moore linux/amd64
16e364572d08 18e5af790473 "/hello" Exited (0) 3 hours ago peaceful_lalande linux/arm64
PS: the column command used here is the one from util-linux not the one from BSD utils. util-linux is a standard package distributed by the Linux Kernel Organization. On macOS, to get it, use brew install util-linux; rockylinux uses it by default and unfortunately on Debian/Ubuntu, the opposite choice has been done (cf https://askubuntu.com/q/1098248).
Working through Jon Erickson's book on Hacking. He uses an intel format assembly code. He provides the following snippet:
reader#hacking:~/booksrc 08048374 <main>:
$ objdump -M intel -D
a.out | grep -A20 main.
I'm getting this error:
Mac-of-Thor:test thorkamphefner$ objdump -M
objdump: Unknown command line argument '-M'. Try: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump -help'
objdump: Did you mean '-C'?
What do I need to do to update objdump?
objdump on a Mac is llvm-objdump, not GNU Binutils objdump that takes command-line options like -Mintel
I think I've read that the standard ways of installing GNU binutils on Mac will give you gobjdump.
See Disassemble into x86_64 on OSX10.6 (But with _Intel_ Syntax)
objdump -disassemble -x86-asm-syntax=intel should work on a Mac (for llvm-objdump).
I'm looking for a POSIX shell/bash command to determine if the OS architecture is 386, amd64, arm, or arm64?
I suggest using:
dpkg --print-architecture
uname -m
prints values such as x86_64, i686, arm, or aarch64.
I went with the following:
architecture=""
case $(uname -m) in
i386) architecture="386" ;;
i686) architecture="386" ;;
x86_64) architecture="amd64" ;;
arm) dpkg --print-architecture | grep -q "arm64" && architecture="arm64" || architecture="arm" ;;
esac
$ lscpu | grep Architecture
Architecture: x86_64
Or if you want to get only the value:
$ lscpu | awk '/Architecture:/{print $2}'
x86_64
$ arch
Also works. Tested on Debian-based and RPM-based distros.
I made a bash script to install a software package on a Linux system.
There are 4 packages I can use to install the software:
x86.deb
x86.rpm
x86_64.deb
x86_64.rpm
I know when to install which package on which Linux server manually, but I would like to find out "automatically" (in my bash script) which one I have to install.
Is there any command to find out?
I already know there is a way to find out the architecture (32-bit or 64-bit) via the "arch" command, but I do not know how to find out which package I need.
uname -m or arch gives you the architecture (x86_64 or similar).
You can probably figure out whether your system is based on RPM or DEB (e. g. Ubuntu is DEB-based) by asking both variants which package installed /bin/ls:
dpkg -S /bin/ls
will print
coreutils: /bin/ls
on a DEB-based system.
rpm -q -f /bin/ls
will print
coreutils-5.97-23.el5_6.4
on an RPM-based system (with probably different version numbers).
On the "wrong" system each of these will give an error message instead.
if dpkg -S /bin/ls >/dev/null 2>&1
then
case "$(arch)" in
x86_64)
sudo dpkg -i x86_64.deb;;
i368)
sudo dpkg -i x86.deb;;
*)
echo "Don't know how to handle $(arch)"
exit 1
;;
esac
elif rpm -q -f /bin/ls >/dev/null 2>&1
then
case "$(arch)" in
x86_64)
sudo rpm -i x86_64.rpm;;
i368)
sudo rpm -i x86.rpm;;
*)
echo "Don't know how to handle $(arch)"
exit 1
;;
esac
else
echo "Don't know this package system (neither RPM nor DEB)."
exit 1
fi
Of course all this only makes sense in case you know what to do then, i. e. if you know which package is to be installed on which package system with which architecture.
I've written some custom shellcode that I want to encode using Metasploit's msfvenom. Back when msfencode was still working this is the way the command would have gone:
$ echo -ne “\x31…\x80” | sudo msfencode -a x86 -t c -e x86/jmp_call_additive
"pipe the shellcode to msfencode for architecture x86 with the output as a c array with the x86/jmp_call_additive encoder"
Now I want to do the same thing except with msfvenom, so I tried:
$ echo -ne "\x31...\x80" | sudo msfvenom -e x86/jmp_call_additive -a x86 -t c
But I get the following error message:
Attempting to read payload from STDIN...
You must select a platform for a custom payload
I thought that giving the -a flag was specifying the correct platform/architecture, I've also tried --platform in place of -a but I still get the same error message.
I'm running this on a on a virtual machine using Ubuntu 32 bit. Thanks for any help
$ echo -ne “\x31...x80" | sudo msfvenom -e x86/jmp_call_additive -a x86 -p - --platform linux -f c
“pipe the custom shellcode into msfvenom with the x86/jmp_call_additive encoder on x86 architecture with a custom payload on a linux platform with a c array output format"